From d5c361f78feb4846f2ce9670f8d79476ca2e5057 Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Wed, 10 Jul 2024 23:25:45 +0200 Subject: [PATCH] Refactor TIModel(s) and TIVarType(s). Also add Models product IDs --- README.md | 7 +- cli/cli.cpp | 10 +- index.html | 9 +- src/TIModel.cpp | 47 ++------ src/TIModel.h | 22 ++-- src/TIModels.cpp | 154 ++++++++------------------ src/TIModels.h | 60 ++-------- src/TIVarFile.cpp | 21 +++- src/TIVarFile.h | 16 +++ src/TIVarType.cpp | 18 +-- src/TIVarType.h | 13 +-- src/TIVarTypes.cpp | 88 ++++----------- src/TIVarTypes.h | 12 +- src/TypeHandlers/STH_ExactRadical.cpp | 2 +- src/TypeHandlers/TH_GenericList.cpp | 2 +- tests.cpp | 6 +- 16 files changed, 155 insertions(+), 332 deletions(-) diff --git a/README.md b/README.md index 7be455f..2900ce6 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ std::cout << basicSource << std::endl; ``` **Example 2**: Here's how to create a TI-Basic program (output: .8xp file) from a string: ```cpp -auto newPrgm = TIVarFile::createNew(TIVarType::createFromName("Program")); // Create an empty "container" first +auto newPrgm = TIVarFile::createNew("Program"); // Create an empty "container" first newPrgm.setVarName("TEST"); // (also an optional parameter above) newPrgm.setContentFromString("ClrHome:Disp \"Hello World!\""); // Set the var's content from a string newPrgm.saveVarToFile("path/to/output/directory/", "myNewPrgrm"); // The extension is added automatically @@ -35,7 +35,10 @@ Integration example: ``` diff --git a/cli/cli.cpp b/cli/cli.cpp index 19b2d7c..27a87a8 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -97,12 +97,12 @@ int main(int argc, char** argv) try { - varvarType = TIVarType::createFromName(typeName); + varvarType = TIVarType(typeName); } catch (std::invalid_argument& e) { cout << typeName << "is not a valid variable type." << endl; cout << "Valid types:"; - for (const auto& type: tivars::types) + for (const auto& type: TIVarTypes::all()) { cout << " " << type.first; } @@ -126,13 +126,13 @@ int main(int argc, char** argv) string modelStr = result["calc"].as(); try { - TIModel model = TIModel::createFromName(modelStr); + TIModel model{modelStr}; file.setCalcModel(model); } catch (invalid_argument& e) { cout << modelStr << "is not a valid calc model." << endl; cout << "Valid models:"; - for (const auto& model: tivars::models) + for (const auto& model: TIModels::all()) { cout << " " << model.first; } @@ -299,7 +299,7 @@ enum FileType getType(const cxxopts::ParseResult& options, const string& filenam if (extension == "txt") return READABLE; - for (const auto& type: tivars::types) + for (const auto& type: TIVarTypes::all()) { const vector& exts = type.second.getExts(); if (std::find(exts.begin(), exts.end(), extension) != exts.end()) diff --git a/index.html b/index.html index 2f028e8..0ed5091 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,13 @@ diff --git a/src/TIModel.cpp b/src/TIModel.cpp index c2149fa..116011b 100644 --- a/src/TIModel.cpp +++ b/src/TIModel.cpp @@ -12,8 +12,8 @@ namespace tivars { - - bool TIModel::supportsType(const TIVarType& type) + + bool TIModel::supportsType(const TIVarType& type) const { const std::vector& exts = type.getExts(); return this->orderID >= 0 && this->orderID < (int)exts.size() && !exts[this->orderID].empty(); @@ -21,45 +21,14 @@ namespace tivars /*** "Constructors" ***/ - /** - * @param string name The version name - * @return TIModel - * @throws \Exception - */ - TIModel TIModel::createFromName(const std::string& name) + TIModel::TIModel(const std::string& name) { if (TIModels::isValidName(name)) { - TIModel model; - model.name = name; - model.orderID = TIModels::getOrderIDFromName(name); - model.flags = TIModels::getFlagsFromName(name); - model.sig = TIModels::getSignatureFromName(name); - return model; + *this = TIModels::fromName(name); } else { - throw std::invalid_argument("Invalid version name"); - } - } - - /** - * @param string sig The signature (magic bytes) - * @return TIModel - * @throws \Exception - */ - TIModel TIModel::createFromSignature(const std::string& sig) - { - if (TIModels::isValidSignature(sig)) - { - TIModel model; - model.sig = sig; - model.orderID = TIModels::getDefaultOrderIDFromSignature(sig); - model.flags = TIModels::getMinFlagsFromSignature(sig); - model.name = TIModels::getDefaultNameFromSignature(sig); - return model; - } else - { - throw std::invalid_argument("Invalid version signature"); + throw std::invalid_argument("Invalid model name"); } } } @@ -71,16 +40,14 @@ namespace tivars class_("TIModel") .constructor<>() .constructor() - .constructor() + .constructor() .function("getOrderId" , &tivars::TIModel::getOrderId) + .function("getProductId", &tivars::TIModel::getProductId) .function("getName" , &tivars::TIModel::getName) .function("getFlags" , &tivars::TIModel::getFlags) .function("getSig" , &tivars::TIModel::getSig) .function("supportsType", &tivars::TIModel::supportsType) - - .class_function("createFromName", &tivars::TIModel::createFromName) - .class_function("createFromSignature", &tivars::TIModel::createFromSignature) ; } #endif diff --git a/src/TIModel.h b/src/TIModel.h index d005655..272b77a 100644 --- a/src/TIModel.h +++ b/src/TIModel.h @@ -18,39 +18,31 @@ namespace tivars { public: - /*** "Constructors" ***/ - /** - * @param string name The version name - */ - static TIModel createFromName(const std::string& name); - - /** - * @param string sig The signature (magic bytes) - */ - static TIModel createFromSignature(const std::string& sig); - TIModel() = default; - TIModel(const std::string& name) { *this = createFromName(name); } - TIModel(const char name[]) { *this = createFromName(name); } + TIModel(const std::string& name); + TIModel(const char* name) { *this = TIModel{std::string{name}}; }; - TIModel(int orderId, const std::string& name, uint32_t flags, const std::string& sig) : orderID(orderId), name(name), flags(flags), sig(sig) + TIModel(int orderId, const std::string& name, uint32_t flags, const std::string& sig, uint8_t productId) + : orderID(orderId), name(name), flags(flags), sig(sig), productId(productId) {} ~TIModel() = default; /* Getters */ int getOrderId() const { return this->orderID; } + int getProductId() const { return this->productId; } std::string getName() const { return this->name; } uint32_t getFlags() const { return this->flags; } std::string getSig() const { return this->sig; } - bool supportsType(const TIVarType& type); + bool supportsType(const TIVarType& type) const; private: int orderID = -1; std::string name = "Unknown"; uint32_t flags = 0; std::string sig = ""; + uint8_t productId = 0; }; diff --git a/src/TIModels.cpp b/src/TIModels.cpp index 7badaee..2e6ba0d 100644 --- a/src/TIModels.cpp +++ b/src/TIModels.cpp @@ -6,37 +6,46 @@ */ #include "TIModels.h" -#include namespace tivars { + namespace + { + std::unordered_map models; + const TIModel unknownModel{}; + } + + TIModel TIModels::fromName(const std::string& name) + { + return isValidName(name) ? models[name] : unknownModel; + } - std::unordered_map models; - - /** - * Make and insert the associative arrays for the model. - * - * @param int|null orderID The orderID (for the extensions association) - * @param uint32_t flags The flags determining available features - * @param string name The name of the calc using this model - * @param string sig The signature (magic bytes) used for this model - */ - void TIModels::insertModel(int orderID, uint32_t flags, const std::string& name, const std::string& sig) + TIModel TIModels::fromSignature(const std::string& sig) { - const TIModel model(orderID, name, flags, sig); + return isValidSignature(sig) ? models[sig] : unknownModel; + } + + TIModel TIModels::fromPID(uint8_t pid) + { + return isValidPID(pid) ? models[std::to_string(pid)] : unknownModel; + } + + // orderID is for the extensions association + void TIModels::insertModel(int orderID, uint32_t flags, const std::string& name, const std::string& sig, uint8_t productId) + { + const TIModel model(orderID, name, flags, sig, productId); if (!models.count(name)) models[name] = model; - const std::string flags_str = std::to_string(flags); - if (!models.count(flags_str)) - models[flags_str] = model; + const std::string pid_str = std::to_string(productId); + if (!models.count(pid_str)) + models[pid_str] = model; if (!models.count(sig)) models[sig] = model; } - // TODO : Research actual compatibility flags/"versions" from libtifiles, and maybe even TI ? void TIModels::initTIModelsArray() { const uint32_t flags82 = 0 | has82things; @@ -51,103 +60,32 @@ namespace tivars const uint32_t flags84pcepy= flags84pce | hasPython; const uint32_t flags82aep = flags83pceep&~hasApps; - insertModel(-1, 0, "Unknown", ""); - insertModel(0, flags82, "82", "**TI82**"); - insertModel(1, flags83, "83", "**TI83**"); - insertModel(2, flags82a, "82A", "**TI83F*"); - insertModel(3, flags84p, "84+T", "**TI83F*"); - insertModel(4, flags83p, "82+", "**TI83F*"); - insertModel(4, flags83p, "83+", "**TI83F*"); - insertModel(4, flags84p, "84+", "**TI83F*"); - insertModel(5, flags84pcse, "84+CSE", "**TI83F*"); - insertModel(6, flags84pce, "84+CE", "**TI83F*"); - insertModel(6, flags84pce, "84+CET", "**TI83F*"); - insertModel(6, flags84pcepy,"84+CETPE","**TI83F*"); - insertModel(6, flags84pcepy,"84+CEPy", "**TI83F*"); - insertModel(7, flags83pce, "83PCE", "**TI83F*"); - insertModel(7, flags83pceep,"83PCEEP", "**TI83F*"); - insertModel(8, flags82aep, "82AEP", "**TI83F*"); - } - - /** - * @param uint32_t flags The model flags - * @return string The model name for those flags - */ - std::string TIModels::getDefaultNameFromFlags(uint32_t flags) - { - const std::string flags_str = std::to_string(flags); - return isValidFlags(flags) ? models[flags_str].getName() : "Unknown"; - } - - /** - * @param string name The model name - * @return uint32_t The model flags for that name - */ - uint32_t TIModels::getFlagsFromName(const std::string& name) - { - return isValidName(name) ? models[name].getFlags() : 0; + // In case of duplicate ProductID for a given orderID, we first insert the default model for that ProductID + insertModel(0, flags82, "82", "**TI82**", 0); + insertModel(1, flags83, "83", "**TI83**", 0); + insertModel(2, flags82a, "82A", "**TI83F*", 0x0B); + insertModel(3, flags84p, "84+T", "**TI83F*", 0x1B); + insertModel(4, flags83p, "83+", "**TI83F*", 0x04); + insertModel(4, flags83p, "82+", "**TI83F*", 0x04); + insertModel(4, flags84p, "84+", "**TI83F*", 0x0A); + insertModel(5, flags84pcse, "84+CSE", "**TI83F*", 0x0F); + insertModel(6, flags84pce, "84+CE", "**TI83F*", 0x13); + insertModel(6, flags84pce, "84+CET", "**TI83F*", 0x13); + insertModel(6, flags84pcepy,"84+CETPE","**TI83F*", 0x13); + insertModel(6, flags84pcepy,"84+CEPy", "**TI83F*", 0x13); + insertModel(7, flags83pce, "83PCE", "**TI83F*", 0x13); + insertModel(7, flags83pceep,"83PCEEP", "**TI83F*", 0x13); + insertModel(8, flags82aep, "82AEP", "**TI83F*", 0x15); } - /** - * @param uint32_t flags The model flags - * @return string The signature for those flags - */ - std::string TIModels::getSignatureFromFlags(uint32_t flags) + const std::unordered_map& TIModels::all() { - const std::string flags_str = std::to_string(flags); - return isValidFlags(flags) ? models[flags_str].getSig() : ""; + return models; } - /** - * @param string name - * @return string The signature for that name - */ - std::string TIModels::getSignatureFromName(const std::string& name) - { - return isValidName(name) ? models[name].getSig() : ""; - } - - /** - * @param string sig The signature - * @return string The default calc name whose file formats use that signature - */ - std::string TIModels::getDefaultNameFromSignature(const std::string& sig) - { - return isValidSignature(sig) ? models[sig].getName() : ""; - } - - /** - * @param string sig The signature - * @return int The default calc order ID whose file formats use that signature - */ - int TIModels::getDefaultOrderIDFromSignature(const std::string& sig) - { - return isValidSignature(sig) ? models[sig].getOrderId() : -1; - } - - /** - * @param string name - * @return int The default calc order ID whose file formats use that signature - */ - int TIModels::getOrderIDFromName(const std::string& name) - { - return isValidName(name) ? models[name].getOrderId() : -1; - } - - /** - * @param string sig The signature - * @return string The minimum compatibility flags for that signaure - */ - uint32_t TIModels::getMinFlagsFromSignature(const std::string& sig) - { - return isValidSignature(sig) ? models[sig].getFlags() : 0; - } - - - bool TIModels::isValidFlags(uint32_t flags) + bool TIModels::isValidPID(uint8_t pid) { - const std::string flags_str = std::to_string(flags); - return (flags != 0 && models.count(flags_str)); + return (pid > 0 && models.count(std::to_string(pid))); } bool TIModels::isValidName(const std::string& name) diff --git a/src/TIModels.h b/src/TIModels.h index d953dd1..bba7e0f 100644 --- a/src/TIModels.h +++ b/src/TIModels.h @@ -8,15 +8,12 @@ #ifndef TIMODELS_H #define TIMODELS_H -#include #include "CommonTypes.h" #include "TIModel.h" -#include "TIVarType.h" +#include namespace tivars { - extern std::unordered_map models; - enum TIFeatureFlags { has82things = 0b000000001, // (1 << 0); @@ -35,60 +32,19 @@ namespace tivars public: - static void initTIModelsArray(); - - static std::string getDefaultNameFromFlags(uint32_t flags); - - /** - * @param std::string name The model name - * @return int The model flags for that name - */ - static uint32_t getFlagsFromName(const std::string& name); - - /** - * @param int flags The model flags - * @return std::string The signature for those flags - */ - static std::string getSignatureFromFlags(uint32_t flags); + static TIModel fromName(const std::string& name); + static TIModel fromSignature(const std::string& sig); + static TIModel fromPID(uint8_t pid); - /** - * @param std::string name - * @return std::string The signature for that name - */ - static std::string getSignatureFromName(const std::string& name); - /** - * @param std::string sig The signature - * @return std::string The default calc name whose file formats use that signature - */ - static std::string getDefaultNameFromSignature(const std::string& sig); - - /** - * @param std::string sig The signature - * @return int The default calc order ID whose file formats use that signature - */ - static int getDefaultOrderIDFromSignature(const std::string& sig); - - /** - * @param std::string name - * @return int The default calc order ID whose file formats use that signature - */ - static int getOrderIDFromName(const std::string& name); - - /** - * @param std::string sig The signature - * @return std::string The minimum compatibility flags for that signaure - */ - static uint32_t getMinFlagsFromSignature(const std::string& sig); - - - static bool isValidFlags(uint32_t flags); + static void initTIModelsArray(); + static const std::unordered_map& all(); + static bool isValidPID(uint8_t pid); static bool isValidName(const std::string& name); - static bool isValidSignature(const std::string& sig); private: - static void insertModel(int orderID, uint32_t flags, const std::string& name, const std::string& sig); + static void insertModel(int orderID, uint32_t flags, const std::string& name, const std::string& sig, uint8_t productId); }; diff --git a/src/TIVarFile.cpp b/src/TIVarFile.cpp index ab4688b..7e87bff 100644 --- a/src/TIVarFile.cpp +++ b/src/TIVarFile.cpp @@ -18,6 +18,8 @@ #include #include +#include "TIVarTypes.h" + namespace tivars { @@ -90,7 +92,7 @@ namespace tivars TIVarFile TIVarFile::createNew(const TIVarType& type, const std::string& name) { - return createNew(type, name, "84+CE"); + return TIVarFile(type, name, TIModel{"84+CE"}); } TIVarFile TIVarFile::createNew(const TIVarType& type) @@ -112,7 +114,14 @@ namespace tivars std::copy(sig_extra.begin(), sig_extra.end(), this->header.sig_extra); std::copy(comment.begin(), comment.end(), this->header.comment); this->header.entries_len = this->get_two_bytes_swapped(); - this->calcModel = TIModel::createFromSignature(signature); // TODO: check sig_extra bytes instead/too since it has the PID which may be more precise + + // the calcModel may later get updated with a more precise one + if (TIModels::isValidPID(header.ownerPID)) + this->calcModel = TIModels::fromPID(header.ownerPID); + else if (TIModels::isValidSignature(signature)) + this->calcModel = TIModels::fromSignature(signature); + else + throw std::invalid_argument("Unhandled file type. No known model usable for this header."); } void TIVarFile::makeVarEntriesFromFile() @@ -256,7 +265,7 @@ namespace tivars if (memcmp(&data[2], STH_PythonAppVar::ID_CODE, 4) == 0 || memcmp(&data[2], STH_PythonAppVar::ID_SCRIPT, 4) == 0) { - _type = TIVarType::createFromName("PythonAppVar"); + _type = TIVarType{"PythonAppVar"}; } } } @@ -501,9 +510,9 @@ namespace tivars .function("saveVarToFile" , select_overload(&tivars::TIVarFile::saveVarToFile)) .class_function("loadFromFile", &tivars::TIVarFile::loadFromFile) - .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) - .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) - .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) + .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) + .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) + .class_function("createNew", select_overload(&tivars::TIVarFile::createNew)) ; } #endif diff --git a/src/TIVarFile.h b/src/TIVarFile.h index 5f1e08b..12d7435 100644 --- a/src/TIVarFile.h +++ b/src/TIVarFile.h @@ -71,6 +71,22 @@ namespace tivars static TIVarFile createNew(const TIVarType& type, const std::string& name); static TIVarFile createNew(const TIVarType& type); + // Additional overloads for easier Emscripten usage +#ifdef __EMSCRIPTEN__ + static TIVarFile createNew(const std::string& type, const std::string& name, const std::string& model) + { + return TIVarFile{TIVarType{type}, name, TIModel{model}}; + } + static TIVarFile createNew(const std::string& type, const std::string& name) + { + return createNew(TIVarType{type}, name); + } + static TIVarFile createNew(const std::string& type) + { + return createNew(TIVarType{type}); + } +#endif + uint16_t getChecksumValueFromFile(); void setContentFromData(const data_t& data, uint16_t entryIdx); diff --git a/src/TIVarType.cpp b/src/TIVarType.cpp index 588110b..ead2d91 100644 --- a/src/TIVarType.cpp +++ b/src/TIVarType.cpp @@ -14,31 +14,21 @@ namespace tivars { /*** "Constructors" ***/ - /** - * @param uint8_t id The type ID - * @return TIVarType - * @throws \Exception - */ - TIVarType TIVarType::createFromID(uint8_t id) + TIVarType::TIVarType(uint8_t id) { if (TIVarTypes::isValidID(id)) { - return types.at(std::to_string(id)); + *this = TIVarTypes::fromId(id); } else { throw std::invalid_argument("Invalid type ID"); } } - /** - * @param string name The type name - * @return TIVarType - * @throws \Exception - */ - TIVarType TIVarType::createFromName(const std::string& name) + TIVarType::TIVarType(const std::string& name) { if (TIVarTypes::isValidName(name)) { - return types.at(name); + *this = TIVarTypes::fromName(name); } else { throw std::invalid_argument("Invalid type name"); } diff --git a/src/TIVarType.h b/src/TIVarType.h index d104268..a06c1ef 100644 --- a/src/TIVarType.h +++ b/src/TIVarType.h @@ -18,15 +18,14 @@ namespace tivars { public: - /*** "Constructors" ***/ - static TIVarType createFromID(uint8_t id); - static TIVarType createFromName(const std::string& name); - TIVarType() = default; - explicit TIVarType(uint8_t id) { *this = createFromID(id); } - TIVarType(const std::string& name) { *this = createFromName(name); } - TIVarType(const char* name) { *this = createFromName(name); } + explicit TIVarType(uint8_t id); + TIVarType(const std::string& name); + TIVarType(const char* name) { *this = TIVarType{std::string{name}}; } + + static TIVarType createFromID(uint8_t id) { return TIVarType{id}; } + static TIVarType createFromName(const std::string& name) { return TIVarType{name}; } TIVarType(int id, const std::string& name, const std::vector& exts, const handler_pair_t& handlers) : id(id), name(name), exts(exts), handlers(handlers) {} diff --git a/src/TIVarTypes.cpp b/src/TIVarTypes.cpp index 76546db..8db662c 100644 --- a/src/TIVarTypes.cpp +++ b/src/TIVarTypes.cpp @@ -9,7 +9,26 @@ namespace tivars { - std::unordered_map types; + namespace + { + std::unordered_map types; + const TIVarType unknownVarType{}; + } + + const std::unordered_map& TIVarTypes::all() + { + return types; + } + + TIVarType TIVarTypes::fromName(const std::string& name) + { + return isValidName(name) ? types[name] : unknownVarType; + } + + TIVarType TIVarTypes::fromId(uint8_t id) + { + return isValidID(id) ? types[std::to_string(id)] : unknownVarType; + } // Wrap the makeDataFromStr function by one that adds the type/subtype in the options // Ideally, the handlers would parse the string and select the correct handler to dispatch... @@ -19,14 +38,6 @@ namespace tivars return (TH_Generic##which::makeDataFromString)(str, options_withType, _ctx); \ }, &TH_Generic##which::makeStringFromData) - /** - * Make and insert the associative arrays for the type. - * - * @param string name The name of the type - * @param int id The ID of the type - * @param vector exts The extensions the type can have, ordered by feature flags. - * @param pair handlers The data2str and str2data funcs - */ void TIVarTypes::insertType(const std::string& name, int id, const std::vector& exts, const handler_pair_t& handlers) { const TIVarType varType(id, name, exts, handlers); @@ -51,7 +62,6 @@ namespace tivars // 84+ 84+CE-T { const std::string _; - insertType("Unknown", -1, { _ , _ , _ , _ , _ , _ , _ , _ , _ }); /* Standard types */ insertType("Real", 0x00, {"82n", "83n", "8xn", "8xn", "8xn", "8xn", "8xn", "8xn", "8xn"}, GenericHandlerPair(Real, 0x00) ); @@ -105,64 +115,6 @@ namespace tivars insertType("FlashLicense", 0x3E, { _ , _ , _ , _ , _ , _ , _ , _ , _ }); } - /** - * @param int id The type ID - * @return string The type name for that ID - */ - std::string TIVarTypes::getNameFromID(uint8_t id) - { - const std::string id_str = std::to_string(id); - if (types.count(id_str)) - { - return types[id_str].getName(); - } else { - return "Unknown"; - } - } - - /** - * @param string name The type name - * @return int The type ID for that name - */ - int TIVarTypes::getIDFromName(const std::string& name) - { - if (!name.empty() && types.count(name)) - { - return types[name].getId(); - } else { - return -1; - } - } - - /** - * @param uint8_t id The type ID - * @return string[] The array of extensions for that ID - */ - std::vector TIVarTypes::getExtensionsFromTypeID(uint8_t id) - { - const std::string id_str = std::to_string(id); - if (types.count(id_str)) - { - return types[id_str].getExts(); - } else { - return {}; - } - } - - /** - * @param string name - * @return string[] The array of extensions for that ID - */ - std::vector TIVarTypes::getExtensionsFromName(const std::string& name) - { - if (!name.empty() && types.count(name)) - { - return types[name].getExts(); - } else { - return {}; - } - } - bool TIVarTypes::isValidID(uint8_t id) { return types.count(std::to_string(id)); diff --git a/src/TIVarTypes.h b/src/TIVarTypes.h index 3e59c7b..d5960d7 100644 --- a/src/TIVarTypes.h +++ b/src/TIVarTypes.h @@ -14,23 +14,19 @@ namespace tivars { - extern std::unordered_map types; - class TIVarTypes { public: + static TIVarType fromName(const std::string& name); + static TIVarType fromId(uint8_t id); + static void initTIVarTypesArray(); + static const std::unordered_map& all(); static bool isValidName(const std::string& name); - static bool isValidID(uint8_t id); - static std::vector getExtensionsFromName(const std::string& name); - static std::vector getExtensionsFromTypeID(uint8_t id); - static int getIDFromName(const std::string& name); - static std::string getNameFromID(uint8_t id); - private: static void insertType(const std::string& name, int id, const std::vector& exts, const handler_pair_t& handlers = make_handler_pair(DummyHandler)); diff --git a/src/TypeHandlers/STH_ExactRadical.cpp b/src/TypeHandlers/STH_ExactRadical.cpp index 262f84e..251cdab 100644 --- a/src/TypeHandlers/STH_ExactRadical.cpp +++ b/src/TypeHandlers/STH_ExactRadical.cpp @@ -44,7 +44,7 @@ namespace tivars } const auto type = data[0] & ~0x80; // sign bit discarded - if (type != types["ExactRealRadical"].getId() && type != types["ExactComplexRadical"].getId()) + if (type != TIVarType{"ExactRealRadical"}.getId() && type != TIVarType{"ExactComplexRadical"}.getId()) { throw std::invalid_argument("Invalid data bytes - invalid vartype: " + std::to_string(type)); } diff --git a/src/TypeHandlers/TH_GenericList.cpp b/src/TypeHandlers/TH_GenericList.cpp index 99daa24..b68f3a8 100644 --- a/src/TypeHandlers/TH_GenericList.cpp +++ b/src/TypeHandlers/TH_GenericList.cpp @@ -23,7 +23,7 @@ namespace tivars } const auto type = typeIter->second; - if (type != types["Real"].getId() && type != types["Complex"].getId()) + if (type != TIVarType{"Real"}.getId() && type != TIVarType{"Complex"}.getId()) { throw std::invalid_argument("Invalid type for given string"); } diff --git a/tests.cpp b/tests.cpp index c96da88..799acbd 100644 --- a/tests.cpp +++ b/tests.cpp @@ -46,7 +46,7 @@ int main(int argc, char** argv) /* Tests */ - assert(TIVarTypes::getIDFromName("ExactRealPi") == 32); + assert(TIVarType{"ExactRealPi"}.getId() == 32); { TIVarFile testReal = TIVarFile::createNew("Real"); @@ -181,7 +181,7 @@ int main(int argc, char** argv) const auto& entries = clibs.getVarEntries(); assert(entries.size() == 9); for (int i=0; i<9; i++) { - assert(entries[i].typeID == TIVarTypes::getIDFromName("AppVar")); + assert(entries[i].typeID == TIVarType{"AppVar"}.getId()); } assert((char*)entries[1].varname == std::string("GRAPHX")); cout << clibs.getReadableContent() << "\n" << endl; @@ -358,7 +358,7 @@ End)"; } #endif - assert(TIVarTypes::getIDFromName("ExactRealPi") == 32); + assert(TIVarType{"ExactRealPi"}.getId() == 32); { TIVarFile testPrgm = TIVarFile::loadFromFile("testData/Program.8xp");