| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "tools/mac/power/power_sampler/csv_exporter.h" |
| |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "base/strings/stringprintf.h" |
| |
| namespace power_sampler { |
| |
| std::unique_ptr<CsvExporter> CsvExporter::Create(base::TimeTicks time_base, |
| base::FilePath file_path) { |
| base::File output_file(file_path, |
| base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
| if (!output_file.IsValid()) |
| return nullptr; |
| |
| return Create(time_base, std::move(output_file)); |
| } |
| |
| std::unique_ptr<CsvExporter> CsvExporter::Create(base::TimeTicks time_base, |
| base::File file) { |
| return base::WrapUnique(new CsvExporter(time_base, std::move(file))); |
| } |
| |
| CsvExporter::~CsvExporter() = default; |
| |
| void CsvExporter::OnStartSession(const DataColumnKeyUnits& data_columns_units) { |
| for (const auto& kv : data_columns_units) { |
| bool inserted = column_keys_.emplace(kv.first).second; |
| DCHECK(inserted); |
| } |
| |
| std::string header_string = "time(s)"; |
| for (const auto& key : column_keys_) { |
| const auto it = data_columns_units.find(key); |
| DCHECK(it != data_columns_units.end()); |
| const std::string& units = it->second; |
| |
| base::StringAppendF(&header_string, ",%s_%s(%s)", key.sampler_name.c_str(), |
| key.column_name.c_str(), units.c_str()); |
| } |
| |
| header_string.push_back('\n'); |
| |
| bool success = Append(header_string); |
| DCHECK(success) << "Append(header_string) failed."; |
| } |
| |
| bool CsvExporter::OnSample(base::TimeTicks sample_time, |
| const DataRow& data_row) { |
| std::string row_string; |
| |
| base::TimeDelta delta = sample_time - time_base_; |
| base::StringAppendF(&row_string, "%g", delta.InSecondsF()); |
| for (const auto& key : column_keys_) { |
| auto it = data_row.find(key); |
| if (it != data_row.end()) |
| base::StringAppendF(&row_string, ",%g", it->second); |
| else |
| row_string.push_back(','); |
| } |
| row_string.push_back('\n'); |
| |
| // End the session on failure to write. |
| return !Append(row_string); |
| } |
| |
| void CsvExporter::OnEndSession() {} |
| |
| CsvExporter::CsvExporter(base::TimeTicks time_base, base::File file) |
| : time_base_(time_base), file_(std::move(file)) { |
| DCHECK(file_.IsValid()); |
| } |
| |
| bool CsvExporter::Append(const std::string& text) { |
| int result = file_.WriteAtCurrentPos(text.data(), text.size()); |
| if (result == base::checked_cast<int>(text.size())) |
| return true; |
| |
| LOG(ERROR) << "WriteAtCurrentPos failed"; |
| |
| return false; |
| } |
| |
| } // namespace power_sampler |