/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* BitcoinExchange.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: aortigos +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/23 19:54:20 by aortigos #+# #+# */ /* Updated: 2026/04/23 19:54:20 by aortigos ### ########.fr */ /* */ /* ************************************************************************** */ #include "BitcoinExchange.hpp" using std::cout; using std::endl; ////////////////// // Constructors // ////////////////// BitcoinExchange::BitcoinExchange() { // std::cout << "BitcoinExchange default constructor called" << std::endl; } BitcoinExchange::BitcoinExchange(const BitcoinExchange &other) { *this = other; // std::cout << "BitcoinExchange copy constructor called" << std::endl; } BitcoinExchange& BitcoinExchange::operator=(const BitcoinExchange &other) { if (this != &other) { this->data = other.data; } // std::cout << "BitcoinExchange copy assignment operator called" << std::endl; return (*this); } BitcoinExchange::~BitcoinExchange() { // std::cout << "BitcoinExchange destructor called" << std::endl; } void BitcoinExchange::readDatabase(std::ifstream &db) { std::string line; std::getline(db, line); if (line != "date,exchange_rate") throw std::exception(); size_t pos; std::string date; std::string price; while (std::getline(db, line)) { pos = line.find(','); if (pos == std::string::npos) continue ; date = line.substr(0, pos); price = line.substr(pos + 1); this->data[date] = std::strtod(price.c_str(), NULL); } } void BitcoinExchange::execute(std::ifstream &db) { std::string line; std::getline(db, line); if (line != "date | value") throw std::exception(); size_t pos; std::string date; std::string value; while (std::getline(db, line)) { pos = line.find('|'); if (pos == std::string::npos) { cout << "Error: bad input => " << line << endl; continue; } date = line.substr(0, pos); value = line.substr(pos + 1); while (date.size() && date[date.size() - 1] == ' ') date.erase(date.size() - 1); while (value.size() && value[0] == ' ') value.erase(0, 1); if (!validateAll(date, value)) continue ; std::map::iterator it = this->data.lower_bound(date); if (it == this->data.begin() && it->first != date) { cout << "Error: bad input => " << date << endl; continue; } if (it->first != date) it--; cout << date << " => " << value << " = " << it->second * std::strtod(value.c_str(), NULL) << endl; } } bool BitcoinExchange::validateAll(const std::string &date, const std::string &value) { int res; res = validateValue(value); if (!validateDate(date)) { cout << "Error: bad input => " << date << endl; return (false); } else if (res == 1) { cout << "Error: not a number." << endl; return (false); } else if (res == 2) { cout << "Error: not a positive number." << endl; return (false); } else if (res == 3) { cout << "Error: too large a number." << endl; return (false); } return (true); } bool BitcoinExchange::validateDate(const std::string &date) { int maxDay = 31; int year; int month; int day; bool bisiesto; if (date.length() != 10 || date[4] != '-' || date[7] != '-') return (false); for (int i = 0; i < 10; i++) { if (i == 4 || i == 7) continue; if (!isdigit(date[i])) return (false); } year = std::atoi(date.substr(0, 4).c_str()); month = std::atoi(date.substr(5, 2).c_str()); day = std::atoi(date.substr(8, 2).c_str()); bisiesto = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); if (year < 2008) return (false); if (month < 1 || month > 12) return (false); if (month == 4 || month == 6 || month == 9 || month == 11) maxDay = 30; else if (month == 2) { if (bisiesto) maxDay = 29; else maxDay = 28; } if (day < 1 || day > maxDay) return (false); return (true); } int BitcoinExchange::validateValue(const std::string &value) { char *endptr; double val = std::strtod(value.c_str(), &endptr); if (*endptr != '\0') return (1); if (val < 0) return (2); else if (val > 1000) return (3); return (0); }