[ox/fs] Make FileAddress model use builtin union support

This commit is contained in:
Gary Talent 2020-04-16 23:34:08 -05:00
parent 5265a94a80
commit 3ff4a59373

View File

@ -23,10 +23,7 @@ enum class FileAddressType: int8_t {
class FileAddress { class FileAddress {
template<typename T> template<typename T>
friend ox::Error modelRead(T*, FileAddress*); friend ox::Error model(T*, FileAddress*);
template<typename T>
friend ox::Error modelWrite(T*, FileAddress*);
public: public:
static constexpr auto TypeName = "ox::FileAddress"; static constexpr auto TypeName = "ox::FileAddress";
@ -34,6 +31,8 @@ class FileAddress {
protected: protected:
union Data { union Data {
static constexpr auto TypeName = "ox::FileAddress::Data";
static constexpr auto Fields = 3;
char *path; char *path;
const char *constPath; const char *constPath;
uint64_t inode; uint64_t inode;
@ -95,72 +94,19 @@ class FileAddress {
}; };
template<typename T> template<typename T>
ox::Error modelRead(T *io, FileAddress *fa) { ox::Error model(T *io, FileAddress::Data *obj) {
io->template setTypeInfo<FileAddress>();
decltype(fa->m_data.inode) inode = 0;
const auto strSize = io->stringLength("path") + 1;
auto path = new char[strSize];
oxReturnError(io->field("path", SerStr(path, strSize - 1)));
oxReturnError(io->field("inode", &inode));
if (strSize) {
fa->m_data.path = path;
fa->m_type = FileAddressType::Path;
} else {
fa->m_data.inode = inode;
fa->m_type = FileAddressType::Inode;
delete[] path;
}
return OxError(0);
}
template<typename T>
ox::Error modelWrite(T *io, FileAddress *fa) {
io->template setTypeInfo<FileAddress>();
switch (fa->m_type) {
case FileAddressType::Path:
case FileAddressType::ConstPath:
{
decltype(fa->m_data.inode) blank = 0;
const auto strSize = ox_strlen(fa->m_data.constPath) + 1;
auto path = ox_malloca(strSize, char, 0);
memcpy(path.get(), fa->m_data.constPath, strSize);
oxReturnError(io->field("path", SerStr(path.get(), strSize - 1)));
oxReturnError(io->field("inode", &blank));
break;
}
case FileAddressType::Inode:
{
char blankPath[1] = "";
oxReturnError(io->field("path", SerStr(blankPath, 0)));
oxReturnError(io->field("inode", &fa->m_data.inode));
break;
}
case FileAddressType::None:
{
char blankPath[1] = "";
decltype(fa->m_data.inode) blankInode = 0;
oxReturnError(io->field("path", SerStr(blankPath, 0)));
oxReturnError(io->field("inode", &blankInode));
break;
}
}
return OxError(0);
}
template<typename T>
ox::Error modelWriteDefinition(T *io, FileAddress::Data *obj) {
io->template setTypeInfo<FileAddress::Data>(); io->template setTypeInfo<FileAddress::Data>();
oxReturnError(io->field("path", &obj->path)); oxReturnError(io->field("path", SerStr(&obj->path)));
oxReturnError(io->field("constPath", &obj->constPath)); oxReturnError(io->field("constPath", SerStr(&obj->path)));
oxReturnError(io->field("inode", &obj->inode)); oxReturnError(io->field("inode", &obj->inode));
return OxError(0); return OxError(0);
} }
template<typename T> template<typename T>
ox::Error modelWriteDefinition(T *io, FileAddress *fa) { ox::Error model(T *io, FileAddress *fa) {
io->template setTypeInfo<FileAddress>(); io->template setTypeInfo<FileAddress>();
oxReturnError(io->field("type", &fa->m_type)); oxReturnError(io->field("type", bit_cast<int8_t*>(&fa->m_type)));
oxReturnError(io->field("data", UnionView(&fa->m_data, fa->m_type))); oxReturnError(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
return OxError(0); return OxError(0);
} }