initial commit
This commit is contained in:
149
os_utils.cc
Normal file
149
os_utils.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// Created on 2024-05-17.
|
||||
//
|
||||
|
||||
#include "os_utils.h"
|
||||
|
||||
#include "utf_convert.h"
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
|
||||
bool ReadFile(std::string_view path, std::vector<uint8_t>& out, size_t maxSize, int& errorCode) {
|
||||
if (maxSize == 0) {
|
||||
errorCode = -EINVAL;
|
||||
return false;
|
||||
}
|
||||
int fd = open(std::string(path).c_str(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
errorCode = -errno;
|
||||
return false;
|
||||
}
|
||||
struct stat64 st{};
|
||||
if (fstat64(fd, &st) < 0) {
|
||||
close(fd);
|
||||
errorCode = -errno;
|
||||
return false;
|
||||
}
|
||||
if (st.st_size > maxSize) {
|
||||
close(fd);
|
||||
errorCode = -EOVERFLOW;
|
||||
return false;
|
||||
}
|
||||
out.resize(st.st_size);
|
||||
ssize_t remaining = st.st_size;
|
||||
ssize_t read = 0;
|
||||
uint8_t* ptr = out.data();
|
||||
while (remaining > 0) {
|
||||
read = ::read(fd, ptr, remaining);
|
||||
if (read < 0) {
|
||||
close(fd);
|
||||
errorCode = -errno;
|
||||
return false;
|
||||
}
|
||||
remaining -= read;
|
||||
ptr += read;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool WriteFile(std::string_view path, std::span<const uint8_t> data, int& errorCode) {
|
||||
int fd = open(std::string(path).c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) {
|
||||
errorCode = -errno;
|
||||
return false;
|
||||
}
|
||||
ssize_t remaining = data.size_bytes();
|
||||
ssize_t written = 0;
|
||||
const uint8_t* ptr = data.data();
|
||||
while (remaining > 0) {
|
||||
written = ::write(fd, ptr, remaining);
|
||||
if (written < 0) {
|
||||
close(fd);
|
||||
errorCode = -errno;
|
||||
return false;
|
||||
}
|
||||
remaining -= written;
|
||||
ptr += written;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <cwchar>
|
||||
|
||||
|
||||
std::string GetErrorMsg(int errorCode) {
|
||||
return strerror(std::abs(errorCode));
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
bool ReadFile(std::string_view path, std::vector<uint8_t>& out, size_t maxSize, int& errorCode) {
|
||||
std::wstring wpath = utfcvt::UTF8ToWide(path);
|
||||
HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
errorCode = -(int) GetLastError();
|
||||
return false;
|
||||
}
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(hFile, &fileSize)) {
|
||||
CloseHandle(hFile);
|
||||
errorCode = -(int) GetLastError();
|
||||
return false;
|
||||
}
|
||||
if (fileSize.QuadPart > maxSize) {
|
||||
CloseHandle(hFile);
|
||||
errorCode = -ERROR_FILE_TOO_LARGE;
|
||||
return false;
|
||||
}
|
||||
out.resize(fileSize.QuadPart);
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(hFile, out.data(), fileSize.LowPart, &bytesRead, nullptr)) {
|
||||
CloseHandle(hFile);
|
||||
errorCode = -(int) GetLastError();
|
||||
return false;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteFile(std::string_view path, std::span<const uint8_t> data, int& errorCode) {
|
||||
std::wstring wpath = utfcvt::UTF8ToWide(path);
|
||||
HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
errorCode = -(int) GetLastError();
|
||||
return false;
|
||||
}
|
||||
DWORD bytesWritten = 0;
|
||||
if (!WriteFile(hFile, data.data(), (DWORD) data.size_bytes(), &bytesWritten, nullptr)) {
|
||||
CloseHandle(hFile);
|
||||
errorCode = -(int) GetLastError();
|
||||
return false;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetErrorMsg(int errorCode) {
|
||||
LPWSTR msgBuf = nullptr;
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &msgBuf, 0, nullptr);
|
||||
std::wstring msg(msgBuf);
|
||||
LocalFree(msgBuf);
|
||||
return utfcvt::WideToUTF8(msg);
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unsupported platform"
|
||||
#endif
|
||||
Reference in New Issue
Block a user