blob: b8e6b1a004e328e1a37936d1e267287593ca05dd [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <optional>
#include <string>
namespace android::incfs {
namespace details {
class CStrWrapper {
public:
CStrWrapper(std::string_view sv) {
if (sv[sv.size()] == '\0') {
mCstr = sv.data();
} else {
mCopy.emplace(sv);
mCstr = mCopy->c_str();
}
}
CStrWrapper(const CStrWrapper&) = delete;
void operator=(const CStrWrapper&) = delete;
CStrWrapper(CStrWrapper&&) = delete;
void operator=(CStrWrapper&&) = delete;
const char* get() const { return mCstr; }
operator const char*() const { return get(); }
private:
const char* mCstr;
std::optional<std::string> mCopy;
};
inline CStrWrapper c_str(std::string_view sv) {
return {sv};
}
} // namespace details
inline bool enabled() {
return IncFs_Enabled();
}
inline Version version() {
return IncFs_Version();
}
inline bool isIncFsPath(std::string_view path) {
return IncFs_IsIncFsPath(details::c_str(path));
}
inline Control mount(std::string_view imagePath, std::string_view targetDir, int32_t flags,
std::chrono::milliseconds timeout, int mode) {
return IncFs_Mount(details::c_str(imagePath), details::c_str(targetDir), flags, timeout.count(),
mode);
}
inline ErrorCode unmount(std::string_view dir) {
return IncFs_Unmount(details::c_str(dir));
}
inline ErrorCode bindMount(std::string_view sourceDir, std::string_view targetDir) {
return IncFs_BindMount(details::c_str(sourceDir), details::c_str(targetDir));
}
inline std::string root(Control control) {
std::string result;
result.resize(PATH_MAX);
size_t size = result.size();
if (IncFs_Root(control, result.data(), &size) < 0) {
return {};
}
result.resize(size);
return result;
}
inline Control open(std::string_view dir) {
return IncFs_Open(details::c_str(dir));
}
inline Inode makeFile(Control control, std::string_view name, Inode parent, Size size,
std::string_view metadata, int mode) {
return IncFs_MakeFile(control, details::c_str(name), parent, size, metadata.begin(),
metadata.size(), mode);
}
inline Inode makeDir(Control control, std::string_view name, Inode parent,
std::string_view metadata, int mode) {
return IncFs_MakeDir(control, details::c_str(name), parent, metadata.begin(), metadata.size(),
mode);
}
inline RawMetadata getMetadata(Control control, Inode inode) {
RawMetadata metadata(INCFS_MAX_FILE_ATTR_SIZE);
size_t size = metadata.size();
if (IncFs_GetMetadata(control, inode, metadata.data(), &size) < 0) {
return {};
}
metadata.resize(size);
return metadata;
}
inline ErrorCode link(Control control, Inode item, Inode targetParent, std::string_view name) {
return IncFs_Link(control, item, targetParent, details::c_str(name));
}
inline ErrorCode unlink(Control control, Inode parent, std::string_view name) {
return IncFs_Unlink(control, parent, details::c_str(name));
}
inline WaitResult waitForPendingReads(Control control, std::chrono::milliseconds timeout,
std::vector<PendingReadInfo>* pendingReadsBuffer) {
static constexpr auto kDefaultBufferSize = INCFS_DEFAULT_PENDING_READ_BUFFER_SIZE;
if (pendingReadsBuffer->empty()) {
pendingReadsBuffer->resize(kDefaultBufferSize);
}
size_t size = pendingReadsBuffer->size();
IncFsErrorCode err =
IncFs_WaitForPendingReads(control, timeout.count(), pendingReadsBuffer->data(), &size);
pendingReadsBuffer->resize(size);
switch (err) {
case 0:
return WaitResult::HaveData;
case -ETIMEDOUT:
return WaitResult::Timeout;
}
return WaitResult(err);
}
inline WaitResult waitForPageReads(Control control, std::chrono::milliseconds timeout,
std::vector<PageReadInfo>* pageReadsBuffer) {
static constexpr auto kDefaultBufferSize =
INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES * PAGE_SIZE / sizeof(PageReadInfo);
if (pageReadsBuffer->empty()) {
pageReadsBuffer->resize(kDefaultBufferSize);
}
size_t size = pageReadsBuffer->size();
IncFsErrorCode err =
IncFs_WaitForPageReads(control, timeout.count(), pageReadsBuffer->data(), &size);
pageReadsBuffer->resize(size);
switch (err) {
case 0:
return WaitResult::HaveData;
case -ETIMEDOUT:
return WaitResult::Timeout;
}
return WaitResult(err);
}
inline ErrorCode writeBlocks(Control control, const incfs_new_data_block blocks[],
int blocksCount) {
return IncFs_WriteBlocks(control, blocks, blocksCount);
}
} // namespace android::incfs