187 lines
4.6 KiB
C++
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
|