175 lines
4.6 KiB
C++
175 lines
4.6 KiB
C++
|
|
#include "primitives/EnumObject.hpp"
|
|
|
|
#include <malloc.h>
|
|
#include <cstring>
|
|
|
|
using namespace tp;
|
|
using namespace obj;
|
|
|
|
void EnumObject::constructor(EnumObject* self) {
|
|
self->active = 0;
|
|
self->nentries = 0;
|
|
self->entries = nullptr;
|
|
}
|
|
|
|
void obj::EnumObject::destructor(EnumObject* self) {
|
|
if (self->entries) free(self->entries);
|
|
}
|
|
|
|
void EnumObject::copy(EnumObject* self, const EnumObject* in) {
|
|
if (self->entries) free(self->entries);
|
|
self->active = in->active;
|
|
self->nentries = in->nentries;
|
|
|
|
self->entries = (alni*) malloc(self->nentries * ENV_ALNI_SIZE_B);
|
|
tp::memCopy(self->entries, in->entries, self->nentries * ENV_ALNI_SIZE_B);
|
|
}
|
|
|
|
void obj::EnumObject::init(tp::InitialierList<const char*> list) {
|
|
|
|
if (entries) free(entries);
|
|
|
|
active = 0;
|
|
nentries = (uhalni) list.size();
|
|
entries = (alni*) malloc(nentries * ENV_ALNI_SIZE_B);
|
|
tp::memSetVal(entries, nentries * ENV_ALNI_SIZE_B, 0);
|
|
|
|
alni* entry = entries;
|
|
for (auto elem : list) {
|
|
|
|
alni len = std::strlen(elem);
|
|
if (len > ENV_ALNI_SIZE_B - 1) len = ENV_ALNI_SIZE_B - 1;
|
|
|
|
tp::memCopy(entry, elem, len);
|
|
|
|
for (alni* chech_entry = entries; chech_entry != entry; chech_entry++) {
|
|
DEBUG_ASSERT(tp::memCompare(chech_entry, entry, ENV_ALNI_SIZE_B) != 0);
|
|
}
|
|
|
|
entry++;
|
|
}
|
|
}
|
|
|
|
const char* obj::EnumObject::getActiveName() { return getItemName(active); }
|
|
|
|
const char* obj::EnumObject::getItemName(tp::uhalni idx) {
|
|
DEBUG_ASSERT(entries && idx >= 0 && idx < nentries);
|
|
return (const char*) (entries + idx);
|
|
}
|
|
|
|
void EnumObject::from_int(EnumObject* self, alni in) {
|
|
if (self->entries && in >= 0 && in < self->nentries) {
|
|
self->active = uhalni(in);
|
|
}
|
|
}
|
|
|
|
void EnumObject::from_float(EnumObject* self, alnf in) {
|
|
if (self->entries && in >= 0 && in < self->nentries) {
|
|
self->active = uhalni(in);
|
|
}
|
|
}
|
|
|
|
void EnumObject::from_string(EnumObject* self, const std::string& in) {
|
|
if (self->entries) {
|
|
alni* entry = self->entries;
|
|
for (uhalni i = 0; i < self->nentries; i++) {
|
|
if (in == ((const char*) entry)) {
|
|
self->active = i;
|
|
}
|
|
entry += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string EnumObject::to_string(EnumObject* self) {
|
|
if (!self->entries) {
|
|
return {};
|
|
}
|
|
auto val = (const char*) (&self->entries[self->active]);
|
|
return val;
|
|
}
|
|
|
|
alni EnumObject::to_int(EnumObject* self) {
|
|
if (!self->entries) {
|
|
return -1;
|
|
}
|
|
return alni(self->active);
|
|
}
|
|
|
|
alnf EnumObject::to_float(EnumObject* self) {
|
|
if (!self->entries) {
|
|
return -1;
|
|
}
|
|
return alnf(self->active);
|
|
}
|
|
|
|
static alni save_size(EnumObject* self) {
|
|
if (!self->entries) {
|
|
return sizeof(uhalni);
|
|
}
|
|
return sizeof(uhalni) + sizeof(uhalni) + sizeof(alni) * self->nentries;
|
|
}
|
|
|
|
static void save(EnumObject* self, ArchiverOut& file_self) {
|
|
if (!self->entries) {
|
|
uhalni empty_code = -1;
|
|
file_self << empty_code;
|
|
return;
|
|
}
|
|
file_self << self->active;
|
|
file_self << self->nentries;
|
|
file_self.writeBytes((tp::int1*) self->entries, self->nentries * ENV_ALNI_SIZE_B);
|
|
}
|
|
|
|
static void load(ArchiverIn& file_self, EnumObject* self) {
|
|
file_self >> self->active;
|
|
if (self->active == -1) {
|
|
self->nentries = 0;
|
|
self->entries = nullptr;
|
|
return;
|
|
}
|
|
file_self >> self->nentries;
|
|
self->entries = (alni*) malloc(self->nentries * ENV_ALNI_SIZE_B);
|
|
file_self.readBytes((tp::int1*) self->entries, self->nentries * ENV_ALNI_SIZE_B);
|
|
}
|
|
|
|
bool obj::EnumObject::compare(EnumObject* first, EnumObject* second) { return first->entries != nullptr && second->entries != nullptr && first->active == second->active; }
|
|
|
|
EnumObject* obj::EnumObject::create(tp::InitialierList<const char*> list) {
|
|
auto enum_object = (EnumObject*) obj::NDO->create("enum");
|
|
enum_object->init(list);
|
|
return enum_object;
|
|
}
|
|
|
|
alni allocated_size(EnumObject* self) {
|
|
alni out = sizeof(uhalni) * 2 + sizeof(tp::alni*);
|
|
if (self->entries) {
|
|
out += self->nentries * sizeof(alni) * 2;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
struct ObjectTypeConversions EnumObjectTypeConversions = {
|
|
.from_int = (object_from_int) EnumObject::from_int,
|
|
.from_float = (object_from_float) EnumObject::from_float,
|
|
.from_string = (object_from_string) EnumObject::from_string,
|
|
.to_string = (object_to_string) EnumObject::to_string,
|
|
.to_int = (object_to_int) EnumObject::to_int,
|
|
.to_float = (object_to_float) EnumObject::to_float,
|
|
};
|
|
|
|
struct obj::ObjectType obj::EnumObject::TypeData = {
|
|
.base = nullptr,
|
|
.constructor = (object_constructor) EnumObject::constructor,
|
|
.destructor = (object_destructor) EnumObject::destructor,
|
|
.copy = (object_copy) EnumObject::copy,
|
|
.size = sizeof(EnumObject),
|
|
.name = "enum",
|
|
.convesions = &EnumObjectTypeConversions,
|
|
.save_size = (object_save_size) save_size,
|
|
.save = (object_save) save,
|
|
.load = (object_load) load,
|
|
.comparison = (object_compare) EnumObject::compare,
|
|
.allocated_size = (object_allocated_size) allocated_size,
|
|
};
|