Files
nostalgia/deps/ox/src/ox/fs/filesystem/filelocation.hpp
Gary Talent 9f338a7429
All checks were successful
Build / build (push) Successful in 3m18s
[ox] Run liccor
2025-01-08 23:03:05 -06:00

187 lines
4.6 KiB
C++

/*
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/std/std.hpp>
#include <ox/model/def.hpp>
#include <ox/model/typenamecatcher.hpp>
#include <ox/model/types.hpp>
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
enum class FileAddressType: int8_t {
None = -1,
Path,
ConstPath,
Inode,
};
template<typename T>
constexpr Error model(T *h, CommonPtrWith<class FileAddress> auto *fa) noexcept;
class FileAddress {
template<typename T>
friend constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept;
public:
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress";
static constexpr auto TypeVersion = 1;
union Data {
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data";
static constexpr auto TypeVersion = 1;
char *path = nullptr;
const char *constPath;
uint64_t inode;
};
protected:
FileAddressType m_type = FileAddressType::None;
Data m_data{};
public:
constexpr FileAddress() noexcept = default;
FileAddress(const FileAddress &other) noexcept;
FileAddress(FileAddress &&other) noexcept;
FileAddress(std::nullptr_t) noexcept;
FileAddress(uint64_t inode) noexcept;
explicit FileAddress(StringViewCR path) noexcept;
constexpr FileAddress(ox::StringLiteral path) noexcept;
constexpr ~FileAddress() noexcept;
FileAddress &operator=(const FileAddress &other) noexcept;
FileAddress &operator=(FileAddress &&other) noexcept;
bool operator==(const FileAddress &other) const noexcept;
bool operator==(StringViewCR path) const noexcept;
[[nodiscard]]
constexpr FileAddressType type() const noexcept {
switch (m_type) {
case FileAddressType::Path:
case FileAddressType::ConstPath:
return FileAddressType::Path;
default:
return m_type;
}
}
constexpr Result<uint64_t> getInode() const noexcept {
switch (m_type) {
case FileAddressType::Inode:
return m_data.inode;
default:
return ox::Error(1);
}
}
constexpr Result<ox::CStringView> getPath() const noexcept {
switch (m_type) {
case FileAddressType::Path:
return ox::CStringView(m_data.path);
case FileAddressType::ConstPath:
return ox::CStringView(m_data.constPath);
default:
return ox::Error(1);
}
}
explicit constexpr operator bool() const noexcept {
return m_type != FileAddressType::None;
}
private:
/**
* Cleanup memory allocations.
*/
constexpr void cleanup() noexcept;
/**
* Clears fields, but does not delete allocations.
*/
constexpr void clear() noexcept;
};
constexpr FileAddress::FileAddress(ox::StringLiteral path) noexcept {
m_data.constPath = path.c_str();
m_type = FileAddressType::ConstPath;
}
constexpr FileAddress::~FileAddress() noexcept {
cleanup();
}
constexpr void FileAddress::cleanup() noexcept {
if (m_type == FileAddressType::Path) {
safeDeleteArray(m_data.path);
clear();
}
}
constexpr void FileAddress::clear() noexcept {
m_data.path = nullptr;
m_type = FileAddressType::None;
}
template<>
constexpr const char *getModelTypeName<FileAddress::Data>() noexcept {
return FileAddress::Data::TypeName;
}
template<>
constexpr const char *getModelTypeName<FileAddress>() noexcept {
return FileAddress::TypeName;
}
template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress::Data>());
OX_RETURN_ERROR(h->fieldCString("path", &obj->path));
OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path));
OX_RETURN_ERROR(h->field("inode", &obj->inode));
return {};
}
template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress>());
if constexpr(T::opType() == OpType::Reflect) {
int8_t type = -1;
OX_RETURN_ERROR(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, type)));
} else if constexpr(T::opType() == OpType::Read) {
auto type = static_cast<int8_t>(fa->m_type);
OX_RETURN_ERROR(h->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type);
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
} else if constexpr(T::opType() == OpType::Write) {
auto const type = static_cast<int8_t>(fa->m_type);
OX_RETURN_ERROR(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
}
return {};
}
}
OX_CLANG_NOWARN_END