#include "../include/binsaver.hpp" CBinsaver::CBinsaver(std::map &variablesMap) : CSaver(variablesMap) {} CBinsaver::~CBinsaver() {} bool CBinsaver::save(const std::string& fileName) { ssize_t variableCount = m_variables.size(); // ssize_t fileHash = 0; // uint64_t hashWord; std::ofstream ofs(fileName); if (!ofs || !ofs.good()) return false; std::stringstream ss; // write variable count ss << std::to_string(variableCount) + "\n"; // write variables for (auto& i : m_variables) { ss << i.first + " " + i.second.toString() + "\n"; } // calculate file hash // std::stringstream hashSS(ss.str()); // while (hashSS.read(reinterpret_cast(&hashWord), sizeof(hashWord))) { // fileHash ^= hashWord; // } // ss << "hash " + std::to_string(fileHash); ofs << ss.rdbuf(); ofs.close(); return true; } bool CBinsaver::load( const std::string &fileName ) { ssize_t variableCount; std::ifstream ifs(fileName); if (!ifs || !ifs.good()) { m_log = "file reading error"; return false; } std::string buffer; std::getline( ifs, buffer ); // check if variable count is valid if (buffer.size() < 1 || buffer.size() > 10 || !(std::all_of(buffer.begin(), buffer.end(), [](unsigned char ch) { return std::isdigit(ch); }) )) { ifs.close(); m_log = "invalid argument count"; return false; } variableCount = std::stoll(buffer); if (variableCount < 0) { ifs.close(); m_log = "invalid argument count"; return false; } for (;variableCount && std::getline(ifs, buffer); --variableCount) { std::istringstream iss(buffer); std::string varName; std::string numStr; std::string denStr; std::string slash; bool numSign = 0; bool denSign = 0; if (!(iss >> varName >> numStr >> slash >> denStr) || slash != "/") { ifs.close(); m_log = "wrong format"; return false; } if (numStr.at(0) == '-') { numSign = 1; numStr = numStr.substr(1); } if (denStr.at(0) == '-') { denSign = 1; denStr = denStr.substr(1); } if (!(std::all_of(numStr.begin(), numStr.end(), [](unsigned char ch) { return std::isdigit(ch); }) ) || !(std::all_of(denStr.begin(), denStr.end(), [](unsigned char ch) { return std::isdigit(ch); }) )) { ifs.close(); m_log = "invalid number"; return false; } for ( auto &c : numStr) c -= 48; for ( auto &c : denStr) c -= 48; CBigInt *num = new CBigInt(0); uint64_t insertPosition = 0; while (!std::all_of(numStr.begin(), numStr.end(), [](char c) { return c == 0; })) { num->setBit(insertPosition++, CParser::stringDivideDecimal(numStr)); } CBigInt *den = new CBigInt(0); insertPosition = 0; while (!std::all_of(denStr.begin(), denStr.end(), [](char c) { return c == 0; })) { den->setBit(insertPosition++, CParser::stringDivideDecimal(denStr)); } num->m_negative = numSign; den->m_negative = denSign; if (!m_variables.emplace(varName, CRational(num, den)).second) { // delete num; // delete den; // ifs.close(); // m_log = "varable already exists"; // return false; } } ifs.close(); return true; } /* #binsaveformat ##header [64bit varible count] ##one variable [64bit identifier len] [identif] [64bit datalen] [data] ##padding zeros to 8byte multiply [0x0000] [64bit hash] ##hash xor all 64bit chunks */