blob: 8c06363f1db42f7721503e54d8595c3424b002a3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COBALT_ANALYZER_REPORT_MASTER_REPORT_SERIALIZER_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_SERIALIZER_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "analyzer/report_master/report_internal.pb.h"
#include "analyzer/report_master/report_row_iterator.h"
#include "config/report_configs.pb.h"
#include "grpc++/grpc++.h"
namespace cobalt {
namespace analyzer {
// A utility for serializing reports to strings or streams so that they may be
// exported. This is used by ReportExporter.
//
// Usage:
// Construct an instance. Then either invoke SerializeReport() to serialize
// the whole report at once to a string, or else invoke StartSerializingReport()
// followed by multiple invocations of AppendRows() in order to serialize the
// report incrementally.
//
// See also ReportStream in report_stream.h.
class ReportSerializer {
public:
// Constructor
//
// report_config: The metric part names within the ReportVariables of this
// ReportConfig are used as the column headers for the value columns of the
// serialized report. Note that the |report_type| is not taken from here but
// rather from |metadata|. This is because the report being serialized may be
// an auxilliary report rather than the primary report for the ReportConfig.
//
// metadata: The |report_type| is taken from here. Also the list of
// |variable_indices| determines which ReportVariables from |report_config|
// are used, and their order.
//
// export_config: The serialization type (e.g. CSV) is taken from here.
ReportSerializer(const ReportConfig* report_config,
const ReportMetadataLite* metadata,
const ReportExportConfig* export_config);
// Serializes the report described by the parameters passed to the constructor
// and the parameters passed to this method, as described below.
//
// report_rows: The actual row data to be serialized. The type of the rows
// must correspond to the |report_type| from the |metadata| passed to the
// constructor.
//
// serialized_report_out: On success, the string pointed to will contain the
// serialized report.
//
// mime_type_out: On success, the string pointed to will contain the MIME
// type of the generated report.
//
// Returns OK on success. Logs an ERROR and returns a different status
// if the data contained in the arguments is not self-consistent.
grpc::Status SerializeReport(const std::vector<ReportRow>& report_rows,
std::string* serialized_report_out,
std::string* mime_type_out);
// Starts the process of serializing the report described by the parameters
// passed to the constructor. The state of this instance is set up and,
// depending on the serialization type, a header row may be written to
// |stream|. After this method finishes the accessor mime_type() may be used
// to access the MIME type of the report. After this method is invoked the
// method AppendRows() should be invoked repeatedly in order to cause the
// rows of the report to be serialized.
//
// Returns OK on success. Logs an ERROR and returns a different status
// on error.
grpc::Status StartSerializingReport(std::ostream* stream);
// Continues the process of serializing the report described by the parameters
// passed to the constructor. The next batch of rows will be read from
// |row_iterator| and serialized and written to |stream|. The parameter
// |max_bytes| determines how many rows from |row_iterator| will be read,
// serialized and written. If, after writing a row, the total number of bytes
// written by this invocation of AppendRows() is at least |max_bytes|, then
// this invocation of AppendRows() will exit without reading any more rows
// from |row_iterator|.
//
// The type of the rows returned from |row_iterator| must correspond to the
// |report_type| from the |metadata| passed to the constructor.
//
// Returns OK on success. Logs an ERROR and returns a different status
// on error.
grpc::Status AppendRows(size_t max_bytes, ReportRowIterator* row_iterator,
std::ostream* stream);
std::string mime_type() { return mime_type_; }
private:
grpc::Status StartSerializingCSVReport(std::ostream* stream);
grpc::Status AppendCSVRows(size_t max_bytes, ReportRowIterator* row_iterator,
std::ostream* stream);
grpc::Status AppendCSVHeaderRow(std::ostream* stream);
grpc::Status AppendCSVHistogramHeaderRow(std::ostream* stream);
grpc::Status AppendCSVRawDumpHeaderRow(std::ostream* stream);
grpc::Status AppendCSVJointHeaderRow(std::ostream* stream);
grpc::Status AppendCSVHeaderRowVariableNames(std::ostream* stream);
grpc::Status AppendCSVHeaderRowSystemProfileFields(std::ostream* stream);
grpc::Status AppendCSVReportRow(const ReportRow& report_row,
std::ostream* stream);
grpc::Status AppendCSVSystemProfileFields(const SystemProfile& profile,
std::ostream* stream);
grpc::Status AppendCSVHistogramReportRow(const HistogramReportRow& report_row,
std::ostream* stream);
grpc::Status AppendCSVRawDumpReportRow(const RawDumpReportRow& report_row,
std::ostream* stream);
grpc::Status AppendCSVJointReportRow(const JointReportRow& report_row,
std::ostream* stream);
const ReportConfig* report_config_; // not owned
const ReportMetadataLite* metadata_; // not owned
const ReportExportConfig* export_config_; // not owned
// The parameters below are initialized by StartSerializingReport().
size_t num_columns_;
std::vector<std::string> fixed_leftmost_column_values_;
std::string mime_type_;
};
} // namespace analyzer
} // namespace cobalt
#endif // COBALT_ANALYZER_REPORT_MASTER_REPORT_SERIALIZER_H_