blob: 82c2b18b13133bb827a607554746d5c59cb3d548 [file] [log] [blame]
// Copyright 2022 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 "payload-streamer.h"
namespace fastboot {
namespace internal {
// Register a vmo for reading data from the payload
void PayloadStreamer::RegisterVmo(RegisterVmoRequestView request,
RegisterVmoCompleter::Sync& completer) {
if (vmo_) {
completer.Reply(ZX_ERR_ALREADY_BOUND);
return;
}
auto status = mapper_.Map(request->vmo, 0, 0, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE);
if (status != ZX_OK) {
completer.Reply(status);
return;
}
vmo_ = std::move(request->vmo);
completer.Reply(ZX_OK);
}
// Read the payload data into the vmo registered via RegisterVmo(...)
void PayloadStreamer::ReadData(ReadDataRequestView request, ReadDataCompleter::Sync& completer) {
fuchsia_paver::wire::ReadResult result = {};
if (!vmo_) {
completer.Reply(fuchsia_paver::wire::ReadResult::WithErr(ZX_ERR_BAD_STATE));
return;
}
size_t to_read = std::min(mapper_.size(), size_ - read_offset_);
memcpy(mapper_.start(), data_ + read_offset_, to_read);
read_offset_ += to_read;
if (to_read == 0) {
eof_reached_ = true;
completer.Reply(fuchsia_paver::wire::ReadResult::WithEof(eof_reached_));
} else {
// completer.Reply must be called from within this else block since otherwise
// |info| will go out of scope
fuchsia_paver::wire::ReadInfo info{.offset = 0, .size = static_cast<uint64_t>(to_read)};
completer.Reply(fuchsia_paver::wire::ReadResult::WithInfo(
fidl::ObjectView<fuchsia_paver::wire::ReadInfo>::FromExternal(&info)));
}
}
} // namespace internal
} // namespace fastboot