#include <libsolutil/CommonIO.h>
#include <libsolutil/Assertions.h>
#include <fstream>
#if defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#include <termios.h>
#endif
using namespace std;
using namespace solidity::util;
namespace
{
template <typename T>
inline T readFile(boost::filesystem::path const& _file)
{
assertThrow(boost::filesystem::exists(_file), FileNotFound, _file.string());
assertThrow(boost::filesystem::is_regular_file(_file), NotAFile, _file.string());
T ret;
size_t const c_elementSize = sizeof(typename T::value_type);
std::ifstream is(_file.string(), std::ifstream::binary);
assertThrow(is, FileNotFound, _file.string());
is.seekg(0, is.end);
streamoff length = is.tellg();
if (length == 0)
return ret; is.seekg(0, is.beg);
ret.resize((static_cast<size_t>(length) + c_elementSize - 1) / c_elementSize);
is.read(const_cast<char*>(reinterpret_cast<char const*>(ret.data())), static_cast<streamsize>(length));
return ret;
}
}
string solidity::util::readFileAsString(boost::filesystem::path const& _file)
{
return readFile<string>(_file);
}
string solidity::util::readUntilEnd(istream& _stdin)
{
ostringstream ss;
ss << _stdin.rdbuf();
return ss.str();
}
string solidity::util::readBytes(istream& _input, size_t _length)
{
string output;
output.resize(_length);
_input.read(output.data(), static_cast<streamsize>(_length));
if (_input.fail())
output.resize(static_cast<size_t>(_input.gcount()));
return output;
}
#if defined(_WIN32)
class DisableConsoleBuffering
{
public:
DisableConsoleBuffering()
{
m_stdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(m_stdin, &m_oldMode);
SetConsoleMode(m_stdin, m_oldMode & (~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)));
}
~DisableConsoleBuffering()
{
SetConsoleMode(m_stdin, m_oldMode);
}
private:
HANDLE m_stdin;
DWORD m_oldMode;
};
#else
class DisableConsoleBuffering
{
public:
DisableConsoleBuffering()
{
tcgetattr(0, &m_termios);
m_termios.c_lflag &= ~tcflag_t(ICANON);
m_termios.c_lflag &= ~tcflag_t(ECHO);
m_termios.c_cc[VMIN] = 1;
m_termios.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &m_termios);
}
~DisableConsoleBuffering()
{
m_termios.c_lflag |= ICANON;
m_termios.c_lflag |= ECHO;
tcsetattr(0, TCSADRAIN, &m_termios);
}
private:
struct termios m_termios;
};
#endif
int solidity::util::readStandardInputChar()
{
DisableConsoleBuffering disableConsoleBuffering;
return cin.get();
}
string solidity::util::absolutePath(string const& _path, string const& _reference)
{
boost::filesystem::path p(_path);
if (p.begin() == p.end() || (*p.begin() != "." && *p.begin() != ".."))
return _path;
boost::filesystem::path result(_reference);
if (result.filename() != boost::filesystem::path("/"))
result.remove_filename();
for (boost::filesystem::path::iterator it = p.begin(); it != p.end(); ++it)
if (*it == "..")
result = result.parent_path();
else if (*it != ".")
result /= *it;
return result.generic_string();
}
string solidity::util::sanitizePath(string const& _path) {
return boost::filesystem::path(_path).generic_string();
}