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