nstool/lib/libfnd/source/io.cpp

184 lines
3.7 KiB
C++
Raw Normal View History

#include <fnd/io.h>
#include <fnd/StringConv.h>
2018-04-25 04:59:42 +00:00
#include <fnd/SimpleFile.h>
2018-04-15 02:36:43 +00:00
#include <fstream>
2018-04-15 06:00:46 +00:00
#ifdef _WIN32
#include <direct.h>
2018-04-25 04:59:42 +00:00
#include <cstdlib>
2018-04-15 06:00:46 +00:00
#else
#include <sys/stat.h>
#endif
2017-07-02 15:18:59 +00:00
using namespace fnd;
static const std::string kModuleName = "IO";
2017-07-02 15:18:59 +00:00
static const size_t kBlockSize = 0x100000;
2018-04-15 02:36:43 +00:00
size_t io::getFileSize(const std::string& path)
{
std::ifstream f;
f.open(path, std::ios_base::binary | std::ios_base::in);
if (!f.good() || f.eof() || !f.is_open()) { return 0; }
f.seekg(0, std::ios_base::beg);
std::ifstream::pos_type begin_pos = f.tellg();
f.seekg(0, std::ios_base::end);
return static_cast<size_t>(f.tellg() - begin_pos);
}
void io::readFile(const std::string& path, MemoryBlob & blob)
2017-07-02 15:18:59 +00:00
{
2018-04-25 04:59:42 +00:00
fnd::SimpleFile file;
try
2017-07-02 15:18:59 +00:00
{
2018-04-25 04:59:42 +00:00
file.open(path, file.Read);
2017-07-02 15:18:59 +00:00
}
2018-04-25 04:59:42 +00:00
catch (const fnd::Exception&)
{
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
}
size_t filesz, filepos;
filesz = file.size();
2017-07-02 15:18:59 +00:00
try {
blob.alloc(filesz);
}
catch (const fnd::Exception& e)
2017-07-02 15:18:59 +00:00
{
throw fnd::Exception(kModuleName, "Failed to allocate memory for file: " + std::string(e.what()));
2017-07-02 15:18:59 +00:00
}
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
2018-04-25 04:59:42 +00:00
file.read(blob.getBytes() + filepos, kBlockSize);
2017-07-02 15:18:59 +00:00
}
if (filesz)
{
2018-04-25 04:59:42 +00:00
file.read(blob.getBytes() + filepos, filesz);
2017-07-02 15:18:59 +00:00
}
}
void fnd::io::readFile(const std::string& path, size_t offset, size_t len, MemoryBlob& blob)
{
2018-04-25 04:59:42 +00:00
fnd::SimpleFile file;
try
{
file.open(path, file.Read);
} catch (const fnd::Exception&)
{
2018-04-25 04:59:42 +00:00
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
}
2018-04-25 04:59:42 +00:00
size_t filesz, filepos;
filesz = file.size();
file.seek(offset);
if (filesz < len || filesz < offset || filesz < (offset + len))
{
throw Exception(kModuleName, "Failed to open \"" + path + "\": file to small");
}
try
{
2018-04-25 04:59:42 +00:00
blob.alloc(filesz);
} catch (const fnd::Exception& e)
{
throw fnd::Exception(kModuleName, "Failed to allocate memory for file: " + std::string(e.what()));
}
2018-04-25 04:59:42 +00:00
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
2018-04-25 04:59:42 +00:00
file.read(blob.getBytes() + filepos, kBlockSize);
}
2018-04-25 04:59:42 +00:00
if (filesz)
{
2018-04-25 04:59:42 +00:00
file.read(blob.getBytes() + filepos, filesz);
}
}
void io::writeFile(const std::string& path, const MemoryBlob & blob)
2017-07-02 15:18:59 +00:00
{
writeFile(path, blob.getBytes(), blob.getSize());
2017-07-05 09:17:04 +00:00
}
2018-03-22 05:26:22 +00:00
void io::writeFile(const std::string & path, const byte_t * data, size_t len)
2017-07-05 09:17:04 +00:00
{
2018-04-25 04:59:42 +00:00
fnd::SimpleFile file;
try
{
file.open(path, file.Create);
} catch (const fnd::Exception&)
2017-07-05 09:17:04 +00:00
{
2018-04-25 04:59:42 +00:00
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
2017-07-05 09:17:04 +00:00
}
2018-04-25 04:59:42 +00:00
size_t filesz, filepos;
2017-07-05 09:17:04 +00:00
filesz = len;
2017-07-02 15:18:59 +00:00
2017-07-05 09:17:04 +00:00
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
2018-04-25 04:59:42 +00:00
file.write(data + filepos, kBlockSize);
2017-07-05 09:17:04 +00:00
}
if (filesz)
{
2018-04-25 04:59:42 +00:00
file.write(data + filepos, filesz);
2017-07-05 09:17:04 +00:00
}
2017-07-02 15:18:59 +00:00
}
2018-04-15 06:00:46 +00:00
void io::makeDirectory(const std::string& path)
{
#ifdef _WIN32
std::u16string wpath = fnd::StringConv::ConvertChar8ToChar16(path);
2018-04-25 14:22:19 +00:00
_wmkdir((wchar_t*)wpath.c_str());
2018-04-15 06:00:46 +00:00
#else
mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
#endif
2018-04-25 04:59:42 +00:00
}
void fnd::io::getEnvironVar(std::string & var, const std::string & key)
{
#ifdef _WIN32
char* var_tmp = nullptr;
size_t var_len = 0;
_dupenv_s(&var_tmp, &var_len, key.c_str());
if (var_len > 0)
{
var = std::string(var_tmp);
free(var_tmp);
}
#else
char* var_tmp = nullptr;
var_tmp = getenv(key.c_str());
if (var_tmp != nullptr)
{
var = std::string(var_tmp);
}
#endif
}
void fnd::io::appendToPath(std::string& base, const std::string& add)
2018-04-25 04:59:42 +00:00
{
if (add.empty())
return;
if (base.empty())
2018-04-25 04:59:42 +00:00
{
base = add;
}
else
{
if (base[base.length()-1] != io::kPathDivider[0])
base += io::kPathDivider;
base += add;
2018-04-25 04:59:42 +00:00
}
}