Program Listing for File file_system.cpp¶
↰ Return to documentation for file (necsim/file_system.cpp
)
// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details.
#include <string>
#include <sstream>
#include <boost/filesystem.hpp>
#ifdef WIN_INSTALL
#include <windows.h>
#define sleep Sleep
#endif
#include "file_system.h"
#include "custom_exceptions.h"
#include "Logging.h"
namespace necsim
{
void openSQLiteDatabase(const string &database_name, sqlite3*&database)
{
int rc;
if(database_name == ":memory:")
{
rc = sqlite3_open(":memory:", &database);
if(rc != SQLITE_OK && rc != SQLITE_DONE)
{
stringstream ss;
ss << "Could not connect to in-memory database. Error: " << rc << endl;
ss << " (" << sqlite3_errmsg(database) << ")" << endl;
throw FatalException(ss.str());
}
return;
}
#ifdef WIN_INSTALL
rc = sqlite3_open_v2(database_name.c_str(), &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "win32");
#else
rc = sqlite3_open_v2(database_name.c_str(), &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
"unix-dotfile");
#endif
if(rc != SQLITE_OK && rc != SQLITE_DONE)
{
int i = 0;
while((rc != SQLITE_OK && rc != SQLITE_DONE) && i < 10)
{
i++;
sleep(1);
rc = sqlite3_open_v2(database_name.c_str(), &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
"unix-dotfile");
}
// Attempt different opening method if the first fails.
int j = 0;
while((rc != SQLITE_OK && rc != SQLITE_DONE) && j < 10)
{
j++;
sleep(1);
rc = sqlite3_open(database_name.c_str(), &database);
}
if(rc != SQLITE_OK && rc != SQLITE_DONE)
{
stringstream ss;
ss << "ERROR_SQL_010: SQLite database file could not be opened. Check the folder exists and you "
"have write permissions. (REF1) Error code: " << rc << endl;
ss << " Attempted call " << max(i, j) << " times" << endl;
throw FatalException(ss.str());
}
}
}
void createParent(string file)
{
// Boost < 1.59 support
boost::filesystem::path file_path(file);
auto parent = file_path.parent_path().string();
if(parent.length() > 0)
{
std::string::iterator it = parent.end() - 1;
if(*it == '/')
{
parent.erase(it);
}
boost::filesystem::path parent_path(parent);
if(!boost::filesystem::exists(parent_path))
{
if(!parent_path.empty())
{
if(!boost::filesystem::create_directories(parent_path))
{
throw runtime_error("Cannot create parent folder for " + file);
}
}
}
}
}
bool doesExist(string testfile)
{
if(boost::filesystem::exists(testfile))
{
stringstream os;
os << "\rChecking folder existance..." << testfile << " exists. " << endl;
writeInfo(os.str());
return true;
}
else
{
throw runtime_error(
string("ERROR_MAIN_008: FATAL. Input or output folder does not exist: " + testfile + "."));
}
}
bool doesExistNull(string testfile)
{
return testfile == "null" || testfile == "none" || doesExist(testfile);
}
unsigned long cantorPairing(const unsigned long &x1, const unsigned long &x2)
{
return ((x1 + x2) * (x1 + x2 + 1) / 2) + x2;
}
unsigned long elegantPairing(const unsigned long &x1, const unsigned long &x2)
{
if(x1 > x2)
{
return static_cast<unsigned long>(pow(x1, 2) + x1 + x2);
}
return static_cast<unsigned long>(pow(x2, 2) + x1);
}
vector<string> getCsvLineAndSplitIntoTokens(istream &str)
{
vector<string> result;
string line;
getline(str, line);
stringstream lineStream(line);
string cell;
while(getline(lineStream, cell, ','))
{
result.push_back(cell);
}
// This checks for a trailing comma with no data after it.
if(!lineStream && cell.empty())
{
// If there was a trailing comma then add an empty element.
result.emplace_back("");
}
return result;
}
}