Chromium Code Reviews| Index: components/password_manager/core/browser/export/csv_writer.cc |
| diff --git a/components/password_manager/core/browser/export/csv_writer.cc b/components/password_manager/core/browser/export/csv_writer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b174062d511c1dce08d5d872bb99a827e7aa2d06 |
| --- /dev/null |
| +++ b/components/password_manager/core/browser/export/csv_writer.cc |
| @@ -0,0 +1,84 @@ |
| +// Copyright 2014 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 "components/password_manager/core/browser/export/csv_writer.h" |
| + |
| +#include "base/logging.h" |
| + |
| +namespace { |
| + |
| +#if defined(OS_WIN) |
| +const char kLineEnding[] = "\r\n"; |
| +#else |
| +const char kLineEnding[] = "\n"; |
| +#endif |
| + |
| +// Escapes the |raw_value| of one field if needed, and appends it to |out|. |
| +void AppendValue(const std::string& raw_value, std::string* out) { |
| + // Fields containing line breaks (CRLF), double quotes, and commas should be |
| + // enclosed in double-quotes. |
| + if (raw_value.find_first_of("\r\n\",") == std::string::npos) { |
| + *out += raw_value; |
| + return; |
| + } |
| + |
| + // If double-quotes are used to enclose fields, then a double-quote appearing |
| + // inside a field must be escaped by preceding it with another double quote. |
| + out->push_back('\"'); |
| + for (size_t i = 0; i < raw_value.size(); ++i) { |
| + out->push_back(raw_value[i]); |
| + if (raw_value[i] == '\"') |
| + out->push_back('\"'); |
| + } |
| + out->push_back('\"'); |
| +} |
| + |
| +// Appends the platform-specific EOL terminator to |out|. |
| +void AppendLineSeparator(std::string* out) { |
| + *out += kLineEnding; |
| +} |
| + |
| +// Appends a field separator to |out|. |
| +void AppendFieldSeparator(std::string* out) { |
| + out->push_back(','); |
| +} |
| + |
| +} // namespace |
| + |
| +namespace password_manager { |
| + |
| +// static |
| +void CSVWriter::Write(const std::vector<std::string>& column_names, |
| + const std::vector<ColumnNameToValueMap>& records, |
| + std::string* csv) { |
| + DCHECK(csv); |
| + |
| + csv->clear(); |
| + |
| + // Append header row. |
| + typedef std::vector<std::string>::const_iterator ConstFieldIterator; |
|
vasilii
2014/08/06 17:42:16
ConstColumnIterator?
engedy
2014/08/08 17:06:12
Done.
|
| + for (ConstFieldIterator it_column_name = column_names.begin(); |
| + it_column_name != column_names.end(); ++it_column_name) { |
| + if (it_column_name != column_names.begin()) |
| + AppendFieldSeparator(csv); |
| + AppendValue(*it_column_name, csv); |
| + } |
| + AppendLineSeparator(csv); |
| + |
| + // Append every other data record row. |
| + typedef std::vector<ColumnNameToValueMap>::const_iterator ConstRecordIterator; |
| + for (ConstRecordIterator it_row = records.begin(); |
| + it_row != records.end(); ++it_row) { |
| + for (ConstFieldIterator it_column_name = column_names.begin(); |
| + it_column_name != column_names.end(); ++it_column_name) { |
| + if (it_column_name != column_names.begin()) |
| + AppendFieldSeparator(csv); |
| + if (it_row->count(*it_column_name)) |
| + AppendValue(it_row->at(*it_column_name), csv); |
|
vasilii
2014/08/06 17:42:16
It's C++11 feature.
engedy
2014/08/08 17:06:12
Done. Replaced with find()-based solution.
|
| + } |
| + AppendLineSeparator(csv); |
| + } |
| +} |
| + |
| +} // namespace password_manager |