#ifndef BSP_Q7S_MEMORY_SCRATCHAPI_H_ #define BSP_Q7S_MEMORY_SCRATCHAPI_H_ #include #include #include #include #include #include "fsfw/returnvalues/returnvalue.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "linux/utility/utility.h" #include "returnvalues/classIds.h" /** * @brief API for the scratch buffer */ namespace scratch { static constexpr char PREFERED_SDC_KEY[] = "PREFSD"; static constexpr char ALLOC_FAILURE_COUNT[] = "ALLOCERR"; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SCRATCH_BUFFER; static constexpr ReturnValue_t KEY_NOT_FOUND = returnvalue::makeCode(INTERFACE_ID, 0); ReturnValue_t clearValue(std::string key); /** * Write a string to the scratch buffer * @param key * @param string String to write * @return */ ReturnValue_t writeString(std::string key, std::string string); /** * Read a string from the scratch buffer * @param key * @param string Will be set to read string * @return */ ReturnValue_t readString(std::string key, std::string& string); /** * Write a number to the scratch buffer * @tparam T * @tparam * @param key * @param num Number. Template allows to set signed, unsigned and floating point numbers * @return */ template ::value>::type> inline ReturnValue_t writeNumber(std::string key, T num) noexcept; /** * Read a number from the scratch buffer. * @tparam T * @tparam * @param name * @param num * @return */ template ::value>::type> inline ReturnValue_t readNumber(std::string key, T& num) noexcept; // Anonymous namespace namespace { static uint8_t counter = 0; ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& filename) { using namespace std; filename = "/tmp/sro" + std::to_string(counter++); ostringstream oss; oss << "xsc_scratch read " << name << " > " << filename; int result = std::system(oss.str().c_str()); if (result != 0) { if (WEXITSTATUS(result) == 1) { sif::warning << "scratch::readToFile: Key " << name << " does not exist" << std::endl; // Could not find value std::remove(filename.c_str()); return KEY_NOT_FOUND; } else { utility::handleSystemError(result, "scratch::readToFile"); std::remove(filename.c_str()); return returnvalue::FAILED; } } file.open(filename); return returnvalue::OK; } } // End of anonymous namespace template ::value>::type> inline ReturnValue_t writeNumber(std::string key, T num) noexcept { std::ostringstream oss; oss << "xsc_scratch write " << key << " " << std::to_string(num); int result = std::system(oss.str().c_str()); if (result != 0) { utility::handleSystemError(result, "scratch::writeNumber"); return returnvalue::FAILED; } return returnvalue::OK; } template ::value>::type> inline ReturnValue_t readNumber(std::string key, T& num) noexcept { using namespace std; ifstream file; std::string filename; ReturnValue_t result = readToFile(key, file, filename); if (result != returnvalue::OK) { std::remove(filename.c_str()); return result; } string line; if (not std::getline(file, line)) { std::remove(filename.c_str()); return returnvalue::FAILED; } size_t pos = line.find("="); if (pos == string::npos) { sif::warning << "scratch::readNumber: Output file format invalid, " "no \"=\" found" << std::endl; // Could not find value std::remove(filename.c_str()); return KEY_NOT_FOUND; } std::string valueAsString = line.substr(pos + 1); try { num = std::stoi(valueAsString); } catch (std::invalid_argument& e) { sif::warning << "scratch::readNumber: stoi call failed with " << e.what() << std::endl; } std::remove(filename.c_str()); return returnvalue::OK; } } // namespace scratch #endif /* BSP_Q7S_MEMORY_SCRATCHAPI_H_ */