// 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