1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/name_value_pairs_parser.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/command_line.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/process_util.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_tokenizer.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/threading/thread_restrictions.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace chromeos {  // NOLINT
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kQuoteChars[] = "\"";
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNameValuePairsParser::NameValuePairsParser(NameValueMap* map)
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : map_(map) {
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NameValuePairsParser::AddNameValuePair(const std::string& key,
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            const std::string& value) {
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  (*map_)[key] = value;
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(1) << "name: " << key << ", value: " << value;
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NameValuePairsParser::ParseNameValuePairs(const std::string& in_string,
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               const std::string& eq,
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               const std::string& delim) {
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Set up the pair tokenizer.
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StringTokenizer pair_toks(in_string, delim);
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pair_toks.set_quote_chars(kQuoteChars);
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Process token pairs.
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  while (pair_toks.GetNext()) {
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string pair(pair_toks.token());
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (pair.find(eq) == 0) {
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LOG(WARNING) << "Empty key: '" << pair << "'. Aborting.";
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    StringTokenizer keyvalue(pair, eq);
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string key,value;
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (keyvalue.GetNext()) {
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TrimString(keyvalue.token(), kQuoteChars, &key);
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (keyvalue.GetNext()) {
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        TrimString(keyvalue.token(), kQuoteChars, &value);
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (keyvalue.GetNext()) {
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          LOG(WARNING) << "Multiple key tokens: '" << pair << "'. Aborting.";
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          return false;
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (key.empty()) {
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LOG(WARNING) << "Invalid token pair: '" << pair << "'. Aborting.";
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AddNameValuePair(key, value);
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return true;
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NameValuePairsParser::GetSingleValueFromTool(int argc,
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                  const char* argv[],
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                  const std::string& key) {
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CommandLine command_line(argc, argv);
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string output_string;
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(stevenjb,satorux): Make this non blocking: crosbug.com/5603.
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io_for_thread_join;
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (argc < 1 || !base::GetAppOutput(command_line, &output_string)) {
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(WARNING) << "Error excuting: " << command_line.command_line_string();
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TrimWhitespaceASCII(output_string, TRIM_ALL, &output_string);
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddNameValuePair(key, output_string);
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return true;
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NameValuePairsParser::ParseNameValuePairsFromTool(
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int argc,
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const char* argv[],
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& eq,
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& delim) {
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CommandLine command_line(argc, argv);
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string output_string;
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(stevenjb,satorux): Make this non blocking: crosbug.com/5603.
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io_for_thread_join;
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (argc < 1 || !base::GetAppOutput(command_line, &output_string)) {
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(WARNING) << "Error excuting: " << command_line.command_line_string();
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!ParseNameValuePairs(output_string, eq, delim)) {
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(WARNING) << "Error parsing values while excuting: "
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 << command_line.command_line_string();
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return true;
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace chromeos
104