| // 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 <trace-reader/file_reader.h> |
| |
| namespace trace { |
| |
| // static |
| bool FileReader::Create(const char* file_path, RecordConsumer record_consumer, |
| ErrorHandler error_handler, std::unique_ptr<FileReader>* out_reader) { |
| ZX_DEBUG_ASSERT(out_reader != nullptr); |
| |
| FILE* f = fopen(file_path, "rb"); |
| if (f == nullptr) { |
| return false; |
| } |
| |
| out_reader->reset(new FileReader(f, std::move(record_consumer), std::move(error_handler))); |
| return true; |
| } |
| |
| FileReader::FileReader(FILE* file, RecordConsumer record_consumer, ErrorHandler error_handler) |
| : TraceReader(std::move(record_consumer), std::move(error_handler)), file_(file) {} |
| |
| void FileReader::ReadFile() { |
| for (;;) { |
| size_t to_read = buffer_.size() - buffer_end_; |
| size_t actual = fread(buffer_.data() + buffer_end_, 1u, to_read, file_); |
| |
| if (actual == 0) { |
| break; |
| } |
| |
| buffer_end_ += actual; |
| size_t bytes_available = buffer_end_; |
| |
| size_t bytes_consumed; |
| trace::Chunk chunk(reinterpret_cast<const uint64_t*>(buffer_.data()), |
| trace::BytesToWords(bytes_available)); |
| if (!ReadRecords(chunk)) { |
| ReportError("Trace stream is corrupted"); |
| break; |
| } |
| bytes_consumed = bytes_available - trace::WordsToBytes(chunk.remaining_words()); |
| |
| bytes_available -= bytes_consumed; |
| memmove(buffer_.data(), buffer_.data() + bytes_consumed, bytes_available); |
| buffer_end_ = bytes_available; |
| } |
| } |
| |
| } // namespace trace |