126 lines
2.9 KiB
C++
126 lines
2.9 KiB
C++
#include "BitcoinExchange.hpp"
|
|
|
|
BitcoinExchange::BitcoinExchange()
|
|
{}
|
|
|
|
BitcoinExchange::BitcoinExchange(const BitcoinExchange &other)
|
|
{
|
|
this->_data = other._data;
|
|
}
|
|
|
|
BitcoinExchange::~BitcoinExchange()
|
|
{}
|
|
|
|
BitcoinExchange &BitcoinExchange::operator=(const BitcoinExchange &other)
|
|
{
|
|
this->_data = other._data;
|
|
return (*this);
|
|
}
|
|
|
|
bool BitcoinExchange::isValidDate(const std::string &date) const
|
|
{
|
|
if (date.length() != 10)
|
|
return (false);
|
|
if (date[4] != '-' || date[7] != '-')
|
|
return (false);
|
|
int year = std::atoi(date.substr(0, 4).c_str());
|
|
int month = std::atoi(date.substr(5, 2).c_str());
|
|
int day = std::atoi(date.substr(8, 2).c_str());
|
|
if (month < 1 || month > 12 || day < 1)
|
|
return false;
|
|
if (month != 2 && day > (30 + (month + month / 8) % 2))
|
|
return false;
|
|
if (month == 2)
|
|
{
|
|
if (((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
|
|
if (day > 29)
|
|
return false;
|
|
} else if (day > 28)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void BitcoinExchange::loadDatabase(const std::string &filename)
|
|
{
|
|
std::ifstream file(filename.c_str());
|
|
|
|
if (!file.is_open())
|
|
return;
|
|
|
|
std::string line;
|
|
float value = 0.0;
|
|
std::getline(file, line); //skip header
|
|
|
|
while (std::getline(file, line))
|
|
{
|
|
value = std::atof(line.substr(12).c_str());
|
|
if (isValidDate(line.substr(0, 10)) && value >= 0)
|
|
_data[line.substr(0, 10)] = value;
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
float BitcoinExchange::getRate(const std::string &date) const
|
|
{
|
|
std::map<std::string, float>::const_iterator it = _data.upper_bound(date);
|
|
if (it == _data.begin())
|
|
return (-1); //not found
|
|
--it;
|
|
return (it->second);
|
|
}
|
|
|
|
bool BitcoinExchange::is_valide_input(const std::string &line, float &value)
|
|
{
|
|
if (line.length() < 14 || line.find('|') == std::string::npos) {
|
|
std::cerr << "Error: bad input => " << line << std::endl;
|
|
return false;
|
|
}
|
|
if (!isValidDate(line.substr(0, 10))) {
|
|
std::cerr << "Error: bad input => " << line << std::endl;
|
|
return false;
|
|
}
|
|
std::string valStr = line.substr(13);
|
|
char *end;
|
|
value = std::strtof(valStr.c_str(), &end);
|
|
if (*end != '\0')
|
|
{
|
|
std::cerr << "Error: bad input => " << line << std::endl;
|
|
return false;
|
|
}
|
|
if (value > 1000) {
|
|
std::cerr << "Error: too large a number." << std::endl;
|
|
return false;
|
|
}
|
|
if (value < 0) {
|
|
std::cerr << "Error: not a positive number." << std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void BitcoinExchange::processInput(const std::string &filename)
|
|
{
|
|
std::ifstream file(filename.c_str());
|
|
|
|
if (!file.is_open())
|
|
return;
|
|
|
|
float value = 0.0;
|
|
std::string line;
|
|
std::getline(file, line); // skip header
|
|
|
|
while (std::getline(file, line)) {
|
|
if (!is_valide_input(line, value))
|
|
continue;
|
|
std::string date = line.substr(0, 10);
|
|
float rate = getRate(date);
|
|
if (rate < 0) {
|
|
std::cerr << "Error: bad input => " << date << std::endl;
|
|
continue;
|
|
}
|
|
std::cout << date << " => " << value << " = " << value * rate << std::endl;
|
|
}
|
|
file.close();
|
|
}
|