blob: 5892fbbc4bd4afe2eaf59614e2128185979bf71b [file] [log] [blame]
// Copyright 2018 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/mediaplayer/demux/file_reader.h"
#include <fcntl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <unistd.h>
#include "lib/fsl/io/fd.h"
#include "lib/fxl/files/file_descriptor.h"
namespace media_player {
// static
std::shared_ptr<FileReader> FileReader::Create(zx::channel file_channel) {
return std::make_shared<FileReader>(
fsl::OpenChannelAsFileDescriptor(std::move(file_channel)));
}
FileReader::FileReader(fxl::UniqueFD fd)
: dispatcher_(async_get_default_dispatcher()), fd_(std::move(fd)) {
FXL_DCHECK(dispatcher_);
result_ = fd_.is_valid() ? Result::kOk : Result::kNotFound;
if (result_ == Result::kOk) {
off_t seek_result = lseek(fd_.get(), 0, SEEK_END);
if (seek_result >= 0) {
size_ = static_cast<uint64_t>(seek_result);
} else {
size_ = kUnknownSize;
// TODO(dalesat): More specific error code.
result_ = Result::kUnknownError;
}
}
}
FileReader::~FileReader() {}
void FileReader::Describe(DescribeCallback callback) {
async::PostTask(dispatcher_, [this, callback = std::move(callback)]() {
callback(result_, size_, true);
});
}
void FileReader::ReadAt(size_t position, uint8_t* buffer, size_t bytes_to_read,
ReadAtCallback callback) {
FXL_DCHECK(position < size_);
if (result_ != Result::kOk) {
callback(result_, 0);
return;
}
off_t seek_result = lseek(fd_.get(), position, SEEK_SET);
if (seek_result < 0) {
FXL_LOG(ERROR) << "seek failed, result " << seek_result << " errno "
<< errno;
// TODO(dalesat): More specific error code.
result_ = Result::kUnknownError;
callback(result_, 0);
return;
}
ssize_t result = fxl::ReadFileDescriptor(
fd_.get(), reinterpret_cast<char*>(buffer), bytes_to_read);
if (result < 0) {
// TODO(dalesat): More specific error code.
result_ = Result::kUnknownError;
callback(result_, 0);
return;
}
async::PostTask(dispatcher_, [callback = std::move(callback), result]() {
callback(Result::kOk, result);
});
}
} // namespace media_player