lin
2025-08-01 633231e833e21d5b8b1c00cb15aedb62b3b78e8f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (c) 2013 The Chromium OS 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 "conversion_utils.h"
 
#include <stdlib.h>
#include <unistd.h>
 
#include <string>
#include <vector>
 
#include "base/logging.h"
 
#include "compat/proto.h"
#include "compat/string.h"
#include "file_utils.h"
#include "perf_parser.h"
#include "perf_protobuf_io.h"
#include "perf_reader.h"
 
namespace quipper {
 
namespace {
 
// Parse options from the format strings, set the options, and return the base
// format. Returns the empty string if options are not recognized.
string ParseFormatOptions(string format, PerfParserOptions* options) {
  auto dot = format.find('.');
  if (dot != string::npos) {
    string opt = format.substr(dot + 1);
    format = format.substr(0, dot);
    if (opt == "remap") {
      options->do_remap = true;
    } else if (opt == "discard") {
      options->discard_unused_events = true;
    } else if (opt == "remap.discard") {
      options->do_remap = true;
      options->discard_unused_events = true;
    } else {
      LOG(ERROR) << "Unknown option: " << opt;
      return "";
    }
  }
  return format;
}
 
// ReadInput reads the input and stores it within |reader|.
bool ReadInput(const FormatAndFile& input, PerfReader* reader,
               PerfParserOptions* options) {
  LOG(INFO) << "Reading input.";
 
  string format = ParseFormatOptions(input.format, options);
  if (format == kPerfFormat) {
    return reader->ReadFile(input.filename);
  }
 
  if (format == kProtoTextFormat) {
    PerfDataProto perf_data_proto;
    std::vector<char> data;
    if (!FileToBuffer(input.filename, &data)) return false;
    string text(data.begin(), data.end());
    if (!TextFormat::ParseFromString(text, &perf_data_proto)) return false;
 
    return reader->Deserialize(perf_data_proto);
  }
 
  LOG(ERROR) << "Unimplemented read format: " << input.format;
  return false;
}
 
// WriteOutput reads from |reader| and writes the output to the file
// within |output|.
bool WriteOutput(const FormatAndFile& output, const PerfParserOptions& options,
                 PerfReader* reader) {
  LOG(INFO) << "Writing output.";
 
  // Apply use PerfParser to modify data in reader, applying hacks all hacks,
  // regardless of output format.
  PerfParser parser(reader, options);
  if (!parser.ParseRawEvents()) return false;
 
  string output_string;
  if (output.format == kPerfFormat) {
    return reader->WriteFile(output.filename);
  }
 
  if (output.format == kProtoTextFormat) {
    PerfDataProto perf_data_proto;
    reader->Serialize(&perf_data_proto);
 
    // Serialize the parser stats as well.
    PerfSerializer::SerializeParserStats(parser.stats(), &perf_data_proto);
 
    // Reset the timestamp field since it causes reproducability issues when
    // testing.
    perf_data_proto.set_timestamp_sec(0);
    if (!TextFormat::PrintToString(perf_data_proto, &output_string))
      return false;
    std::vector<char> data(output_string.begin(), output_string.end());
    return BufferToFile(output.filename, data);
  }
 
  LOG(ERROR) << "Unimplemented write format: " << output.format;
  return false;
}
 
}  // namespace
 
// Format string for perf.data.
const char kPerfFormat[] = "perf";
 
// Format string for protobuf text format.
const char kProtoTextFormat[] = "text";
 
bool ConvertFile(const FormatAndFile& input, const FormatAndFile& output) {
  PerfReader reader;
  PerfParserOptions options;
  if (!ReadInput(input, &reader, &options)) return false;
  if (!WriteOutput(output, options, &reader)) return false;
  return true;
}
 
}  // namespace quipper