mirror of
https://github.com/ksherlock/dot_clean.git
synced 2025-01-20 14:31:39 +00:00
updated finder_info, mapped_file, etc
This commit is contained in:
parent
faec01b209
commit
d12a961627
@ -29,6 +29,12 @@
|
|||||||
#include "applefile.h"
|
#include "applefile.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
||||||
#endif
|
#endif
|
||||||
@ -78,12 +84,12 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
#if defined(__sun__)
|
#if defined(__sun__)
|
||||||
fd = attropen(path.c_str(), XATTR_RESOURCEFORK_NAME, O_RDONLY);
|
fd = attropen(path.c_str(), XATTR_RESOURCEFORK_NAME, O_RDONLY | O_BINARY);
|
||||||
#else
|
#else
|
||||||
std::string p(path);
|
std::string p(path);
|
||||||
p += ":" XATTR_RESOURCEFORK_NAME;
|
p += ":" XATTR_RESOURCEFORK_NAME;
|
||||||
|
|
||||||
fd = open(p.c_str(), O_RDONLY);
|
fd = open(p.c_str(), O_RDONLY | O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
@ -117,7 +123,7 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
return rv;
|
return rv;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int fd = open(path.c_str(), O_RDONLY);
|
int fd = open(path.c_str(), O_RDONLY | O_BINARY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
return rv;
|
return rv;
|
||||||
@ -127,8 +133,11 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
ssize_t size = size_xattr(fd, XATTR_RESOURCEFORK_NAME);
|
ssize_t size = size_xattr(fd, XATTR_RESOURCEFORK_NAME);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
if (errno != ENOATTR)
|
if (errno == ENOATTR) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
rv.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ec = std::error_code(errno, std::generic_category());
|
||||||
close(fd);
|
close(fd);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -138,6 +147,10 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
ssize_t rsize = read_xattr(fd, XATTR_RESOURCEFORK_NAME, rv.data(), size);
|
ssize_t rsize = read_xattr(fd, XATTR_RESOURCEFORK_NAME, rv.data(), size);
|
||||||
if (rsize < 0) {
|
if (rsize < 0) {
|
||||||
if (errno == ERANGE || errno == EINTR) continue; // try again.
|
if (errno == ERANGE || errno == EINTR) continue; // try again.
|
||||||
|
if (errno == ENOATTR) {
|
||||||
|
rv.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
rv.clear();
|
rv.clear();
|
||||||
break;
|
break;
|
||||||
@ -210,13 +223,13 @@ void one_file(const std::string &infile, const std::string &outfile) {
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
||||||
finder_info_helper fi;
|
finder_info_helper fi;
|
||||||
bool fi_ok = fi.open(infile);
|
bool fi_ok = fi.open(infile, ec);
|
||||||
|
|
||||||
|
|
||||||
// ENOATTR is ok... but that's not an errc...
|
// ENOATTR is ok... but that's not an errc...
|
||||||
std::vector<uint8_t> resource = read_resource_fork(infile, ec);
|
std::vector<uint8_t> resource = read_resource_fork(infile, ec);
|
||||||
|
|
||||||
if (ec && ec.value() != ENOATTR) {
|
if (ec) {
|
||||||
warnc(ec.value(), "%s resource fork\n", infile.c_str());
|
warnc(ec.value(), "%s resource fork\n", infile.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -230,7 +243,7 @@ void one_file(const std::string &infile, const std::string &outfile) {
|
|||||||
if (fi_ok) count++;
|
if (fi_ok) count++;
|
||||||
|
|
||||||
|
|
||||||
int fd = open(outfile.c_str(), O_WRONLY | O_CREAT, 0666);
|
int fd = open(outfile.c_str(), O_WRONLY | O_CREAT | O_BINARY, 0666);
|
||||||
memset(&head, 0, sizeof(head));
|
memset(&head, 0, sizeof(head));
|
||||||
head.magicNum = htonl(APPLEDOUBLE_MAGIC);
|
head.magicNum = htonl(APPLEDOUBLE_MAGIC);
|
||||||
head.versionNum = htonl(0x00020000);
|
head.versionNum = htonl(0x00020000);
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#include "applefile.h"
|
#include "applefile.h"
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
||||||
@ -78,12 +81,12 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
#if defined(__sun__)
|
#if defined(__sun__)
|
||||||
fd = attropen(path.c_str(), XATTR_RESOURCEFORK_NAME, O_RDONLY);
|
fd = attropen(path.c_str(), XATTR_RESOURCEFORK_NAME, O_RDONLY | O_BINARY);
|
||||||
#else
|
#else
|
||||||
std::string p(path);
|
std::string p(path);
|
||||||
p += ":" XATTR_RESOURCEFORK_NAME;
|
p += ":" XATTR_RESOURCEFORK_NAME;
|
||||||
|
|
||||||
fd = open(p.c_str(), O_RDONLY);
|
fd = open(p.c_str(), O_RDONLY | O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
@ -117,7 +120,7 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
return rv;
|
return rv;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int fd = open(path.c_str(), O_RDONLY);
|
int fd = open(path.c_str(), O_RDONLY | O_BINARY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
return rv;
|
return rv;
|
||||||
@ -127,8 +130,11 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
ssize_t size = size_xattr(fd, XATTR_RESOURCEFORK_NAME);
|
ssize_t size = size_xattr(fd, XATTR_RESOURCEFORK_NAME);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
if (errno != ENOATTR)
|
if (errno == ENOATTR) {
|
||||||
ec = std::error_code(errno, std::generic_category());
|
rv.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ec = std::error_code(errno, std::generic_category());
|
||||||
close(fd);
|
close(fd);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -138,6 +144,10 @@ std::vector<uint8_t> read_resource_fork(const std::string &path, std::error_code
|
|||||||
ssize_t rsize = read_xattr(fd, XATTR_RESOURCEFORK_NAME, rv.data(), size);
|
ssize_t rsize = read_xattr(fd, XATTR_RESOURCEFORK_NAME, rv.data(), size);
|
||||||
if (rsize < 0) {
|
if (rsize < 0) {
|
||||||
if (errno == ERANGE || errno == EINTR) continue; // try again.
|
if (errno == ERANGE || errno == EINTR) continue; // try again.
|
||||||
|
if (errno == ENOATTR) {
|
||||||
|
rv.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
ec = std::error_code(errno, std::generic_category());
|
ec = std::error_code(errno, std::generic_category());
|
||||||
rv.clear();
|
rv.clear();
|
||||||
break;
|
break;
|
||||||
@ -210,13 +220,14 @@ void one_file(const std::string &infile, const std::string &outfile) {
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
||||||
finder_info_helper fi;
|
finder_info_helper fi;
|
||||||
bool fi_ok = fi.open(infile);
|
|
||||||
|
bool fi_ok = fi.open(infile, ec);
|
||||||
|
|
||||||
|
|
||||||
// ENOATTR is ok... but that's not an errc...
|
// ENOATTR is ok... but that's not an errc...
|
||||||
std::vector<uint8_t> resource = read_resource_fork(infile, ec);
|
std::vector<uint8_t> resource = read_resource_fork(infile, ec);
|
||||||
|
|
||||||
if (ec && ec.value() != ENOATTR) {
|
if (ec) {
|
||||||
warnc(ec.value(), "%s resource fork\n", infile.c_str());
|
warnc(ec.value(), "%s resource fork\n", infile.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -230,7 +241,7 @@ void one_file(const std::string &infile, const std::string &outfile) {
|
|||||||
if (fi_ok) count++;
|
if (fi_ok) count++;
|
||||||
|
|
||||||
|
|
||||||
int fd = open(outfile.c_str(), O_WRONLY | O_CREAT, 0666);
|
int fd = open(outfile.c_str(), O_WRONLY | O_CREAT | O_BINARY, 0666);
|
||||||
memset(&head, 0, sizeof(head));
|
memset(&head, 0, sizeof(head));
|
||||||
head.magicNum = htonl(APPLESINGLE_MAGIC);
|
head.magicNum = htonl(APPLESINGLE_MAGIC);
|
||||||
head.versionNum = htonl(0x00020000);
|
head.versionNum = htonl(0x00020000);
|
||||||
|
@ -267,10 +267,11 @@ void one_file(const std::string &data, const std::string &rsrc) noexcept try {
|
|||||||
});
|
});
|
||||||
|
|
||||||
finder_info_helper fi;
|
finder_info_helper fi;
|
||||||
bool fi_ok = false;
|
std::error_code ec;
|
||||||
bool update_fi = false;
|
bool update_fi = false;
|
||||||
|
bool fi_ok = false;
|
||||||
|
|
||||||
fi_ok = fi.open(data, false);
|
fi_ok = fi.open(data, finder_info_helper::read_write, ec);
|
||||||
|
|
||||||
std::for_each(begin, end, [&](const ASEntry &tmp){
|
std::for_each(begin, end, [&](const ASEntry &tmp){
|
||||||
|
|
||||||
@ -320,7 +321,7 @@ void one_file(const std::string &data, const std::string &rsrc) noexcept try {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (update_fi) {
|
if (update_fi) {
|
||||||
if (!fi.write()) {
|
if (!fi.write(ec)) {
|
||||||
throw_errno("com.apple.FinderInfo");
|
throw_errno("com.apple.FinderInfo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,19 +8,28 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "xattr.h"
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
#include <sys/xattr.h>
|
||||||
#define XATTR_FINDERINFO_NAME "user.com.apple.FinderInfo"
|
#define XATTR_FINDERINFO_NAME "user.com.apple.FinderInfo"
|
||||||
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
#define XATTR_RESOURCEFORK_NAME "user.com.apple.ResourceFork"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/extattr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_AIX)
|
||||||
|
#include <sys/ea.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
#define XATTR_FINDERINFO_NAME "AFP_AfpInfo"
|
#define XATTR_FINDERINFO_NAME "AFP_AfpInfo"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -198,24 +207,241 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int fi_open(const std::string &path, bool read_only) {
|
template<class T>
|
||||||
|
T _(const T t, std::error_code &ec) {
|
||||||
|
if (t < 0) ec = std::error_code(errno, std::generic_category());
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* extended attributes functions.
|
||||||
|
*/
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
ssize_t size_xattr(int fd, const char *xattr) {
|
||||||
|
return fgetxattr(fd, xattr, NULL, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_xattr(int fd, const char *xattr, void *buffer, size_t size) {
|
||||||
|
return fgetxattr(fd, xattr, buffer, size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write_xattr(int fd, const char *xattr, const void *buffer, size_t size) {
|
||||||
|
if (fsetxattr(fd, xattr, buffer, size, 0, 0) < 0) return -1;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_xattr(int fd, const char *xattr) {
|
||||||
|
return fremovexattr(fd, xattr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
|
ssize_t size_xattr(int fd, const char *xattr) {
|
||||||
|
return fgetxattr(fd, xattr, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_xattr(int fd, const char *xattr, void *buffer, size_t size) {
|
||||||
|
return fgetxattr(fd, xattr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write_xattr(int fd, const char *xattr, const void *buffer, size_t size) {
|
||||||
|
if (fsetxattr(fd, xattr, buffer, size, 0) < 0) return -1;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_xattr(int fd, const char *xattr) {
|
||||||
|
return fremovexattr(fd, xattr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
ssize_t size_xattr(int fd, const char *xattr) {
|
||||||
|
return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, xattr, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_xattr(int fd, const char *xattr, void *buffer, size_t size) {
|
||||||
|
return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, xattr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write_xattr(int fd, const char *xattr, const void *buffer, size_t size) {
|
||||||
|
return extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, xattr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_xattr(int fd, const char *xattr) {
|
||||||
|
return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, xattr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(_AIX)
|
||||||
|
ssize_t size_xattr(int fd, const char *xattr) {
|
||||||
|
/*
|
||||||
|
struct stat64x st;
|
||||||
|
if (fstatea(fd, xattr, &st) < 0) return -1;
|
||||||
|
return st.st_size;
|
||||||
|
*/
|
||||||
|
return fgetea(fd, xattr, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_xattr(int fd, const char *xattr, void *buffer, size_t size) {
|
||||||
|
return fgetea(fd, xattr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write_xattr(int fd, const char *xattr, const void *buffer, size_t size) {
|
||||||
|
if (fsetea(fd, xattr, buffer, size, 0) < 0) return -1;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_xattr(int fd, const char *xattr) {
|
||||||
|
return fremoveea(fd, xattr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void set_or_throw_error(std::error_code *ec, int error, const std::string &what) {
|
||||||
|
if (ec) *ec = std::error_code(error, std::system_category());
|
||||||
|
else throw std::system_error(error, std::system_category(), what);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* allocating a new string could reset GetLastError() to 0.
|
||||||
|
*/
|
||||||
|
void set_or_throw_error(std::error_code *ec, const char *what) {
|
||||||
|
auto e = GetLastError();
|
||||||
|
set_or_throw_error(ec, e, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_or_throw_error(std::error_code *ec, const std::string &what) {
|
||||||
|
auto e = GetLastError();
|
||||||
|
set_or_throw_error(ec, e, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
HANDLE CreateFileX(const std::string &s, Args... args) {
|
||||||
|
return CreateFileA(s.c_str(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
HANDLE CreateFileX(const std::wstring &s, Args... args) {
|
||||||
|
return CreateFileW(s.c_str(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fi_close(void *fd) {
|
||||||
|
CloseHandle(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *fi_open(const std::string &path, int perm, std::error_code &ec) {
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
|
||||||
#if defined(__sun__)
|
|
||||||
if (read_only) return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDONLY);
|
|
||||||
else return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDWR | O_CREAT, 0666);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
std::string s(path);
|
std::string s(path);
|
||||||
s.append(":" XATTR_FINDERINFO_NAME);
|
s.append(":" XATTR_FINDERINFO_NAME);
|
||||||
if (read_only) return open(s.c_str(), O_RDONLY | O_BINARY);
|
|
||||||
else return open(s.c_str(), O_RDWR | O_CREAT | O_BINARY, 0666);
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
HANDLE fh;
|
||||||
|
bool ro = perm == 1;
|
||||||
|
|
||||||
|
fh = CreateFileX(s,
|
||||||
|
ro ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
ro ? OPEN_EXISTING : OPEN_ALWAYS,
|
||||||
|
ro ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (fh == INVALID_HANDLE_VALUE)
|
||||||
|
set_or_throw_error(&ec, "CreateFile");
|
||||||
|
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *fi_open(const std::wstring &path, int perm, std::error_code &ec) {
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
|
||||||
|
std::wstring s(path);
|
||||||
|
s.append(L":" XATTR_FINDERINFO_NAME);
|
||||||
|
|
||||||
|
HANDLE fh;
|
||||||
|
bool ro = perm == 1;
|
||||||
|
|
||||||
|
fh = CreateFileX(s,
|
||||||
|
ro ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
ro ? OPEN_EXISTING : OPEN_ALWAYS,
|
||||||
|
ro ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (fh == INVALID_HANDLE_VALUE)
|
||||||
|
set_or_throw_error(&ec, "CreateFile");
|
||||||
|
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fi_write(void *handle, const void *data, int length, std::error_code &ec) {
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
DWORD rv = 0;
|
||||||
|
BOOL ok;
|
||||||
|
|
||||||
|
LARGE_INTEGER zero = { 0 };
|
||||||
|
|
||||||
|
ok = SetFilePointerEx(handle, zero, nullptr, FILE_BEGIN);
|
||||||
|
if (!ok) {
|
||||||
|
set_or_throw_error(&ec, "SetFilePointerEx");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ok = WriteFile(handle, data, length, &rv, nullptr);
|
||||||
|
if (!ok) {
|
||||||
|
set_or_throw_error(&ec, "WriteFile");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fi_read(void *handle, void *data, int length, std::error_code &ec) {
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
DWORD rv = 0;
|
||||||
|
BOOL ok;
|
||||||
|
LARGE_INTEGER zero = { 0 };
|
||||||
|
|
||||||
|
ok = SetFilePointerEx(handle, zero, nullptr, FILE_BEGIN);
|
||||||
|
if (!ok) {
|
||||||
|
set_or_throw_error(&ec, "SetFilePointerEx");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ok = ReadFile(handle, data, length, &rv, nullptr);
|
||||||
|
if (!ok) {
|
||||||
|
set_or_throw_error(&ec, "ReadFile");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void fi_close(int fd) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fi_open(const std::string &path, int perm, std::error_code &ec) {
|
||||||
|
|
||||||
|
#if defined(__sun__)
|
||||||
|
if (perm == 1) return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDONLY);
|
||||||
|
else return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDWR | O_CREAT, 0666);
|
||||||
|
#else
|
||||||
|
// linux needs to open as read/write to write it?
|
||||||
|
//return open(path.c_str(), read_only ? O_RDONLY : O_RDWR);
|
||||||
return open(path.c_str(), O_RDONLY);
|
return open(path.c_str(), O_RDONLY);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int fi_write(int fd, const void *data, int length) {
|
|
||||||
#if defined(__sun__) || defined(_WIN32)
|
int fi_write(int fd, const void *data, int length, std::error_code &ec) {
|
||||||
|
#if defined(__sun__)
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
return write(fd, data, length);
|
return write(fd, data, length);
|
||||||
#else
|
#else
|
||||||
@ -223,8 +449,8 @@ namespace {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int fi_read(int fd, void *data, int length) {
|
int fi_read(int fd, void *data, int length, std::error_code &ec) {
|
||||||
#if defined(__sun__) || defined(_WIN32)
|
#if defined(__sun__)
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
return read(fd, data, length);
|
return read(fd, data, length);
|
||||||
#else
|
#else
|
||||||
@ -232,6 +458,9 @@ namespace {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
void afp_init(struct AFP_Info *info) {
|
void afp_init(struct AFP_Info *info) {
|
||||||
//static_assert(sizeof(AFP_Info) == 60, "Incorrect AFP_Info size");
|
//static_assert(sizeof(AFP_Info) == 60, "Incorrect AFP_Info size");
|
||||||
@ -274,10 +503,12 @@ enum {
|
|||||||
void afp_synchronize(struct AFP_Info *info, int trust) {
|
void afp_synchronize(struct AFP_Info *info, int trust) {
|
||||||
// if ftype/auxtype is inconsistent between prodos and finder info, use
|
// if ftype/auxtype is inconsistent between prodos and finder info, use
|
||||||
// prodos as source of truth.
|
// prodos as source of truth.
|
||||||
uint16_t f;
|
uint16_t f = 0;
|
||||||
uint32_t a;
|
uint32_t a = 0;
|
||||||
if (finder_info_to_filetype(info->finder_info, &f, &a) != 0) return;
|
if (finder_info_to_filetype(info->finder_info, &f, &a)) {
|
||||||
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
||||||
|
}
|
||||||
|
|
||||||
if (trust == trust_prodos)
|
if (trust == trust_prodos)
|
||||||
file_type_to_finder_info(info->finder_info, info->prodos_file_type, info->prodos_aux_type);
|
file_type_to_finder_info(info->finder_info, info->prodos_file_type, info->prodos_aux_type);
|
||||||
else {
|
else {
|
||||||
@ -300,71 +531,150 @@ finder_info_helper::finder_info_helper() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
finder_info_helper::~finder_info_helper() {
|
void finder_info_helper::close() {
|
||||||
|
#if _WIN32
|
||||||
|
if (_fd != INVALID_HANDLE_VALUE) CloseHandle(_fd);
|
||||||
|
_fd = INVALID_HANDLE_VALUE;
|
||||||
|
#else
|
||||||
if (_fd >= 0) close(_fd);
|
if (_fd >= 0) close(_fd);
|
||||||
|
_fd = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
finder_info_helper::~finder_info_helper() {
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finder_info_helper::open(const std::string &name, bool read_only) {
|
bool finder_info_helper::open(const std::string &name, open_mode perm, std::error_code &ec) {
|
||||||
|
|
||||||
if (_fd >= 0) {
|
ec.clear();
|
||||||
close(_fd);
|
|
||||||
_fd = -1;
|
close();
|
||||||
|
|
||||||
|
if (perm < 1 || perm > 3) {
|
||||||
|
ec = std::make_error_code(std::errc::invalid_argument);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
int fd = fi_open(name, read_only);
|
|
||||||
if (fd < 0) return false;
|
|
||||||
|
|
||||||
int ok = read(fd);
|
auto fd = fi_open(name, perm, ec);
|
||||||
// if write mode, it's ok if finder info doesn't exist (yet).
|
if (ec) return false;
|
||||||
if (!read_only && !ok) ok = true;
|
|
||||||
|
|
||||||
if (read_only) close(fd);
|
// win32 should read even if write-only.
|
||||||
else _fd = fd;
|
bool ok = read(_fd, ec);
|
||||||
|
|
||||||
return ok;
|
if (perm == read_only) {
|
||||||
|
fi_close(fd);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write mode, so it's ok if it doesn't exist.
|
||||||
|
if (!ok) ec.clear();
|
||||||
|
_fd = fd;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
bool finder_info_helper::open(const std::wstring &name, open_mode perm, std::error_code &ec) {
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (perm < 1 || perm > 3) {
|
||||||
|
ec = std::make_error_code(std::errc::invalid_argument);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fd = fi_open(name, perm, ec);
|
||||||
|
if (ec) return false;
|
||||||
|
|
||||||
|
// win32 should read even if write-only.
|
||||||
|
bool ok = read(_fd, ec);
|
||||||
|
|
||||||
|
if (perm == read_only) {
|
||||||
|
fi_close(fd);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write mode, so it's ok if it doesn't exist.
|
||||||
|
if (!ok) ec.clear();
|
||||||
|
_fd = fd;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finder_info_helper::read(int fd) {
|
bool finder_info_helper::read(void *fd, std::error_code &ec) {
|
||||||
#if defined(_WIN32)
|
|
||||||
int ok = fi_read(fd, &_afp, sizeof(_afp));
|
int ok = fi_read(fd, &_afp, sizeof(_afp), ec);
|
||||||
|
if (ec) {
|
||||||
|
afp_init(&_afp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (ok < sizeof(_afp) || !afp_verify(&_afp)) {
|
if (ok < sizeof(_afp) || !afp_verify(&_afp)) {
|
||||||
|
ec = std::make_error_code(std::errc::illegal_byte_sequence); // close enough!
|
||||||
afp_init(&_afp);
|
afp_init(&_afp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!_afp.prodos_file_type && !_afp.prodos_aux_type)
|
if (!_afp.prodos_file_type && !_afp.prodos_aux_type)
|
||||||
afp_synchronize(&_afp, trust_hfs);
|
afp_synchronize(&_afp, trust_hfs);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool finder_info_helper::write(void *fd, std::error_code &ec) {
|
||||||
|
return fi_write(fd, &_afp, sizeof(_afp), ec) == sizeof(_afp);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int ok = fi_read(fd, &_finder_info, sizeof(_finder_info));
|
|
||||||
|
bool finder_info_helper::read(int fd, std::error_code &ec) {
|
||||||
|
|
||||||
|
int ok = fi_read(fd, &_finder_info, sizeof(_finder_info), ec);
|
||||||
if (ok < 0) {
|
if (ok < 0) {
|
||||||
memset(&_finder_info, 0, sizeof(_finder_info));
|
memset(&_finder_info, 0, sizeof(_finder_info));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finder_info_to_filetype(_finder_info, &_prodos_file_type, &_prodos_aux_type);
|
finder_info_to_filetype(_finder_info, &_prodos_file_type, &_prodos_aux_type);
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finder_info_helper::write(int fd) {
|
bool finder_info_helper::write(int fd, std::error_code &ec) {
|
||||||
#if defined(_WIN32)
|
return fi_write(fd, &_finder_info, sizeof(_finder_info), ec) == sizeof(_finder_info);
|
||||||
return fi_write(fd, &_afp, sizeof(_afp));
|
}
|
||||||
#else
|
|
||||||
return fi_write(fd, &_finder_info, sizeof(_finder_info));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
bool finder_info_helper::write() {
|
bool finder_info_helper::write(std::error_code &ec) {
|
||||||
return write(_fd);
|
ec.clear();
|
||||||
|
return write(_fd, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool finder_info_helper::write(const std::string &name) {
|
bool finder_info_helper::write(const std::string &name, std::error_code &ec) {
|
||||||
int fd = fi_open(name, false);
|
ec.clear();
|
||||||
if (fd < 0) return false;
|
auto fd = fi_open(name, write_only, ec);
|
||||||
bool ok = write(fd);
|
|
||||||
close(fd);
|
if (ec)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool ok = write(fd, ec);
|
||||||
|
fi_close(fd);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool finder_info_helper::write(const std::wstring &name, std::error_code &ec) {
|
||||||
|
ec.clear();
|
||||||
|
auto fd = fi_open(name, write_only, ec);
|
||||||
|
|
||||||
|
if (ec)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool ok = write(fd, ec);
|
||||||
|
fi_close(fd);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void finder_info_helper::set_prodos_file_type(uint16_t ftype, uint32_t atype) {
|
void finder_info_helper::set_prodos_file_type(uint16_t ftype, uint32_t atype) {
|
||||||
_prodos_file_type = ftype;
|
_prodos_file_type = ftype;
|
||||||
@ -385,6 +695,15 @@ bool finder_info_helper::is_text() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool finder_info_helper::is_binary() const {
|
||||||
|
if (is_text()) return false;
|
||||||
|
if (_prodos_file_type || _prodos_aux_type) return true;
|
||||||
|
|
||||||
|
if (memcmp(_finder_info, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t finder_info_helper::file_type() const {
|
uint32_t finder_info_helper::file_type() const {
|
||||||
uint32_t rv = 0;
|
uint32_t rv = 0;
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#pragma pack(push, 2)
|
#pragma pack(push, 2)
|
||||||
struct AFP_Info {
|
struct AFP_Info {
|
||||||
@ -22,6 +25,12 @@ class finder_info_helper {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum open_mode {
|
||||||
|
read_only = 1,
|
||||||
|
write_only = 2,
|
||||||
|
read_write = 3,
|
||||||
|
};
|
||||||
|
|
||||||
finder_info_helper();
|
finder_info_helper();
|
||||||
~finder_info_helper();
|
~finder_info_helper();
|
||||||
|
|
||||||
@ -33,26 +42,50 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
const uint8_t *finder_info() const {
|
const uint8_t *finder_info() const {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return _afp.finder_info;
|
return _afp.finder_info;
|
||||||
#else
|
#else
|
||||||
return _finder_info;
|
return _finder_info;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *finder_info() {
|
uint8_t *finder_info() {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return _afp.finder_info;
|
return _afp.finder_info;
|
||||||
#else
|
#else
|
||||||
return _finder_info;
|
return _finder_info;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool read(const std::string &fname);
|
bool read(const std::string &fname, std::error_code &ec) {
|
||||||
bool write(const std::string &fname);
|
return open(fname, read_only, ec);
|
||||||
bool open(const std::string &fname, bool read_only = true);
|
}
|
||||||
bool write();
|
|
||||||
|
bool write(const std::string &fname, std::error_code &ec);
|
||||||
|
|
||||||
|
bool open(const std::string &fname, open_mode perm, std::error_code &ec);
|
||||||
|
bool open(const std::string &fname, std::error_code &ec) {
|
||||||
|
return open(fname, read_only, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
bool read(const std::wstring &pathName, std::error_code &ec) {
|
||||||
|
return open(pathName, read_only, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write(const std::wstring &pathName, std::error_code &ec);
|
||||||
|
|
||||||
|
bool open(const std::wstring &fname, open_mode perm, std::error_code &ec);
|
||||||
|
bool open(const std::wstring &fname, std::error_code &ec) {
|
||||||
|
return open(fname, read_only, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool write(std::error_code &ec);
|
||||||
|
|
||||||
uint32_t creator_type() const;
|
uint32_t creator_type() const;
|
||||||
uint32_t file_type() const;
|
uint32_t file_type() const;
|
||||||
@ -80,17 +113,26 @@ public:
|
|||||||
void set_creator_type(uint32_t);
|
void set_creator_type(uint32_t);
|
||||||
|
|
||||||
bool is_text() const;
|
bool is_text() const;
|
||||||
|
bool is_binary() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool write(int fd);
|
void close();
|
||||||
bool read(int fd);
|
|
||||||
|
|
||||||
int _fd = -1;
|
#if defined(_WIN32)
|
||||||
|
bool write(void *handle, std::error_code &ec);
|
||||||
|
bool read(void *handle, std::error_code &ec);
|
||||||
|
#else
|
||||||
|
bool write(int fd, std::error_code &ec);
|
||||||
|
bool read(int fd, std::error_code &ec);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
void *_fd = (void *)-1;
|
||||||
AFP_Info _afp;
|
AFP_Info _afp;
|
||||||
#else
|
#else
|
||||||
|
int _fd = -1;
|
||||||
|
|
||||||
uint16_t _prodos_file_type = 0;
|
uint16_t _prodos_file_type = 0;
|
||||||
uint32_t _prodos_aux_type = 0;
|
uint32_t _prodos_aux_type = 0;
|
||||||
uint8_t _finder_info[32] = {};
|
uint8_t _finder_info[32] = {};
|
||||||
|
@ -32,6 +32,17 @@ namespace {
|
|||||||
set_or_throw_error(ec, e, what);
|
set_or_throw_error(ec, e, what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
HANDLE CreateFileX(const std::string &s, Args... args) {
|
||||||
|
return CreateFileA(s.c_str(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
HANDLE CreateFileX(const std::wstring &s, Args... args) {
|
||||||
|
return CreateFileW(s.c_str(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapped_file_base::close() {
|
void mapped_file_base::close() {
|
||||||
@ -44,7 +55,8 @@ void mapped_file_base::close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
template<class T>
|
||||||
|
void mapped_file_base::open_common(const T& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
||||||
|
|
||||||
if (ec) ec->clear();
|
if (ec) ec->clear();
|
||||||
|
|
||||||
@ -56,7 +68,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
|
|||||||
|
|
||||||
if (is_open()) close();
|
if (is_open()) close();
|
||||||
|
|
||||||
fh = CreateFile(p.c_str(),
|
fh = CreateFileX(p,
|
||||||
flags == readonly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
flags == readonly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -73,7 +85,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
|
|||||||
if (length == -1) {
|
if (length == -1) {
|
||||||
LARGE_INTEGER file_size;
|
LARGE_INTEGER file_size;
|
||||||
GetFileSizeEx(fh, &file_size);
|
GetFileSizeEx(fh, &file_size);
|
||||||
length = file_size.QuadPart;
|
length = (size_t)file_size.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == 0) return;
|
if (length == 0) return;
|
||||||
@ -102,10 +114,13 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
|
|||||||
auto mh_close = make_unique_resource(mh, CloseHandle);
|
auto mh_close = make_unique_resource(mh, CloseHandle);
|
||||||
|
|
||||||
|
|
||||||
|
ULARGE_INTEGER ll;
|
||||||
|
ll.QuadPart = offset;
|
||||||
|
|
||||||
_data = MapViewOfFileEx(mh,
|
_data = MapViewOfFileEx(mh,
|
||||||
access,
|
access,
|
||||||
(DWORD)(offset >> 32),
|
ll.HighPart,
|
||||||
(DWORD)offset,
|
ll.LowPart,
|
||||||
length,
|
length,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (!_data)
|
if (!_data)
|
||||||
@ -118,8 +133,19 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mapped_file_base::open(const std::string &p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
||||||
|
open_common(p, flags, length, offset, ec);
|
||||||
|
}
|
||||||
|
|
||||||
void mapped_file_base::create(const path_type& p, size_t length, std::error_code *ec) {
|
void mapped_file_base::open(const std::wstring &p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
||||||
|
open_common(p, flags, length, offset, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void mapped_file_base::create_common(const T& p, size_t length, std::error_code *ec) {
|
||||||
|
|
||||||
if (ec) ec->clear();
|
if (ec) ec->clear();
|
||||||
|
|
||||||
@ -135,7 +161,7 @@ void mapped_file_base::create(const path_type& p, size_t length, std::error_code
|
|||||||
|
|
||||||
if (is_open()) close();
|
if (is_open()) close();
|
||||||
|
|
||||||
fh = CreateFile(p.c_str(),
|
fh = CreateFileX(p,
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -163,10 +189,13 @@ void mapped_file_base::create(const path_type& p, size_t length, std::error_code
|
|||||||
|
|
||||||
auto mh_close = make_unique_resource(mh, CloseHandle);
|
auto mh_close = make_unique_resource(mh, CloseHandle);
|
||||||
|
|
||||||
|
ULARGE_INTEGER ll;
|
||||||
|
ll.QuadPart = offset;
|
||||||
|
|
||||||
_data = MapViewOfFileEx(mh,
|
_data = MapViewOfFileEx(mh,
|
||||||
access,
|
access,
|
||||||
(DWORD)(offset >> 32),
|
ll.HighPart,
|
||||||
(DWORD)offset,
|
ll.LowPart,
|
||||||
length,
|
length,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
@ -180,7 +209,12 @@ void mapped_file_base::create(const path_type& p, size_t length, std::error_code
|
|||||||
_flags = readwrite;
|
_flags = readwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mapped_file_base::create(const std::string &p, size_t length, std::error_code *ec) {
|
||||||
|
create_common(p, length, ec);
|
||||||
|
}
|
||||||
|
void mapped_file_base::create(const std::wstring &p, size_t length, std::error_code *ec) {
|
||||||
|
create_common(p, length, ec);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -213,7 +247,7 @@ void mapped_file_base::close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
void mapped_file_base::open(const std::string& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
|
||||||
|
|
||||||
if (ec) ec->clear();
|
if (ec) ec->clear();
|
||||||
|
|
||||||
@ -267,7 +301,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapped_file_base::create(const path_type& p, size_t length, std::error_code *ec) {
|
void mapped_file_base::create(const std::string& p, size_t length, std::error_code *ec) {
|
||||||
|
|
||||||
if (ec) ec->clear();
|
if (ec) ec->clear();
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
#ifndef __mapped_file_h__
|
#ifndef __mapped_file_h__
|
||||||
#define __mapped_file_h__
|
#define __mapped_file_h__
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class mapped_file_base {
|
class mapped_file_base {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::string path_type;
|
|
||||||
|
|
||||||
enum mapmode { readonly, readwrite, priv };
|
enum mapmode { readonly, readwrite, priv };
|
||||||
enum createmode { truncate, exclusive };
|
enum createmode { truncate, exclusive };
|
||||||
@ -33,8 +31,22 @@ protected:
|
|||||||
|
|
||||||
void swap(mapped_file_base &rhs);
|
void swap(mapped_file_base &rhs);
|
||||||
|
|
||||||
void open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec);
|
void open(const std::string &p, mapmode flags, size_t length, size_t offset, std::error_code *ec);
|
||||||
void create(const path_type &p, size_t new_size, std::error_code *ec); // always creates readwrite.
|
void create(const std::string &p, size_t new_size, std::error_code *ec); // always creates readwrite.
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void open(const std::wstring &p, mapmode flags, size_t length, size_t offset, std::error_code *ec);
|
||||||
|
void create(const std::wstring &p, size_t new_size, std::error_code *ec); // always creates readwrite.
|
||||||
|
|
||||||
|
template<class S>
|
||||||
|
void open_common(const S &p, mapmode flags, size_t length, size_t offset, std::error_code *ec);
|
||||||
|
|
||||||
|
template<class S>
|
||||||
|
void create_common(const S &p, size_t new_size, std::error_code *ec); // always creates readwrite.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|
||||||
@ -68,22 +80,22 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
mapped_file() = default;
|
mapped_file() = default;
|
||||||
mapped_file(const path_type& p, mapmode flags = readonly, size_t length = -1, size_t offset = 0) {
|
mapped_file(const std::string &p, mapmode flags = readonly, size_t length = -1, size_t offset = 0) {
|
||||||
open(p, flags, length, offset);
|
open(p, flags, length, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped_file(const path_type &p, std::error_code &ec) noexcept {
|
mapped_file(const std::string &p, std::error_code &ec) noexcept {
|
||||||
open(p, readonly, -1, 0, ec);
|
open(p, readonly, -1, 0, ec);
|
||||||
}
|
}
|
||||||
mapped_file(const path_type &p, mapmode flags, std::error_code &ec) noexcept {
|
mapped_file(const std::string &p, mapmode flags, std::error_code &ec) noexcept {
|
||||||
open(p, flags, -1, 0, ec);
|
open(p, flags, -1, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped_file(const path_type &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
|
mapped_file(const std::string &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
|
||||||
open(p, flags, length, 0, ec);
|
open(p, flags, length, 0, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped_file(const path_type &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
|
mapped_file(const std::string &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
|
||||||
open(p, flags, length, offset, ec);
|
open(p, flags, length, offset, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,31 +107,57 @@ public:
|
|||||||
mapped_file &operator=(const mapped_file &) = delete;
|
mapped_file &operator=(const mapped_file &) = delete;
|
||||||
|
|
||||||
|
|
||||||
void open(const path_type& p, mapmode flags, size_t length = -1, size_t offset = 0) {
|
void open(const std::string &p, mapmode flags, size_t length = -1, size_t offset = 0) {
|
||||||
base::open(p, flags, length, offset, nullptr);
|
base::open(p, flags, length, offset, nullptr);
|
||||||
}
|
}
|
||||||
|
void open(const std::string &p, std::error_code &ec) noexcept {
|
||||||
void open(const path_type &p, std::error_code &ec) noexcept {
|
|
||||||
base::open(p, readonly, -1, 0, &ec);
|
base::open(p, readonly, -1, 0, &ec);
|
||||||
}
|
}
|
||||||
void open(const path_type &p, mapmode flags, std::error_code &ec) noexcept {
|
void open(const std::string &p, mapmode flags, std::error_code &ec) noexcept {
|
||||||
base::open(p, flags, -1, 0, &ec);
|
base::open(p, flags, -1, 0, &ec);
|
||||||
}
|
}
|
||||||
void open(const path_type &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
|
void open(const std::string &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
|
||||||
base::open(p, flags, length, 0, &ec);
|
base::open(p, flags, length, 0, &ec);
|
||||||
}
|
}
|
||||||
void open(const path_type &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
|
void open(const std::string &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
|
||||||
base::open(p, flags, length, offset, &ec);
|
base::open(p, flags, length, offset, &ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create(const path_type &p, size_t size) {
|
#ifdef _WIN32
|
||||||
base::create(p, size, nullptr);
|
void open(const std::wstring &p, mapmode flags, size_t length = -1, size_t offset = 0) {
|
||||||
|
base::open(p, flags, length, offset, nullptr);
|
||||||
|
}
|
||||||
|
void open(const std::wstring &p, std::error_code &ec) noexcept {
|
||||||
|
base::open(p, readonly, -1, 0, &ec);
|
||||||
|
}
|
||||||
|
void open(const std::wstring &p, mapmode flags, std::error_code &ec) noexcept {
|
||||||
|
base::open(p, flags, -1, 0, &ec);
|
||||||
|
}
|
||||||
|
void open(const std::wstring &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
|
||||||
|
base::open(p, flags, length, 0, &ec);
|
||||||
|
}
|
||||||
|
void open(const std::wstring &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
|
||||||
|
base::open(p, flags, length, offset, &ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create(const path_type &p, size_t size, std::error_code &ec) noexcept {
|
#endif
|
||||||
|
|
||||||
|
void create(const std::string &p, size_t size) {
|
||||||
|
base::create(p, size, nullptr);
|
||||||
|
}
|
||||||
|
void create(const std::string &p, size_t size, std::error_code &ec) noexcept {
|
||||||
base::create(p, size, &ec);
|
base::create(p, size, &ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void create(const std::wstring &p, size_t size) {
|
||||||
|
base::create(p, size, nullptr);
|
||||||
|
}
|
||||||
|
void create(const std::wstring &p, size_t size, std::error_code &ec) noexcept {
|
||||||
|
base::create(p, size, &ec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const value_type *data() const {
|
const value_type *data() const {
|
||||||
return (const value_type *)_data;
|
return (const value_type *)_data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user