blob: f76c0fb1b6311d1eb2191f12e4c26b92e315c9ee [file] [log] [blame]
// Copyright 2019 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.
#include "garnet/bin/trace2json/trace_parser.h"
#include <lib/syslog/cpp/macros.h>
namespace tracing {
FuchsiaTraceParser::FuchsiaTraceParser(std::ostream* out)
: exporter_(*out),
reader_([this](trace::Record record) { exporter_.ExportRecord(record); },
[](fbl::String error) { FX_LOGS(ERROR) << error.c_str(); }) {}
FuchsiaTraceParser::~FuchsiaTraceParser() = default;
bool FuchsiaTraceParser::ParseComplete(std::istream* in) {
while (!in->eof()) {
size_t bytes_read =
in->read(buffer_.data() + buffer_end_, buffer_.size() - buffer_end_).gcount();
if (bytes_read == 0) {
FX_LOGS(ERROR) << "Read returned 0 bytes";
return false;
}
buffer_end_ += bytes_read;
size_t words = buffer_end_ / sizeof(uint64_t);
trace::Chunk chunk(reinterpret_cast<const uint64_t*>(buffer_.data()), words);
if (!reader_.ReadRecords(chunk)) {
FX_LOGS(ERROR) << "Error parsing trace";
return false;
}
size_t offset = chunk.current_byte_offset();
memmove(buffer_.data(), buffer_.data() + offset, buffer_end_ - offset);
buffer_end_ -= offset;
}
if (buffer_end_ > 0) {
FX_LOGS(ERROR) << "Trace file did not end at a record boundary.";
return false;
}
return true;
}
} // namespace tracing