Add File::size and make File's ctor take StringRef.
This commit is contained in:
parent
f175591923
commit
e34e9fa0c7
39
posix.cc
39
posix.cc
@ -53,6 +53,20 @@
|
|||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#if FMT_GCC_VERSION >= 407
|
||||||
|
# define FMT_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
# define FMT_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FMT_USE_STATIC_ASSERT
|
||||||
|
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
|
||||||
|
#else
|
||||||
|
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
|
||||||
|
# define FMT_STATIC_ASSERT(cond, message) \
|
||||||
|
typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Return type of read and write functions.
|
// Return type of read and write functions.
|
||||||
@ -98,13 +112,13 @@ int fmt::BufferedFile::fileno() const {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::File::File(const char *path, int oflag) {
|
fmt::File::File(fmt::StringRef path, int oflag) {
|
||||||
int mode = S_IRUSR | S_IWUSR;
|
int mode = S_IRUSR | S_IWUSR;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
FMT_POSIX_CALL(sopen_s(&fd_, path, oflag, _SH_DENYNO, mode));
|
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
|
||||||
#else
|
#else
|
||||||
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path, oflag, mode)));
|
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
|
||||||
#endif
|
#endif
|
||||||
if (fd_ == -1)
|
if (fd_ == -1)
|
||||||
throw SystemError(errno, "cannot open file {}", path);
|
throw SystemError(errno, "cannot open file {}", path);
|
||||||
@ -128,6 +142,25 @@ void fmt::File::close() {
|
|||||||
throw SystemError(errno, "cannot close file");
|
throw SystemError(errno, "cannot close file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt::LongLong fmt::File::size() const {
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER size = {};
|
||||||
|
if (!GetFileSizeEx(_get_osfhandle(fd_), &size))
|
||||||
|
throw WindowsError(GetLastError(), "cannot get file size");
|
||||||
|
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(size.QuadPart),
|
||||||
|
"return type of File::size is not large enough");
|
||||||
|
return size.QuadPart;
|
||||||
|
#else
|
||||||
|
typedef struct stat Stat;
|
||||||
|
Stat file_stat = Stat();
|
||||||
|
if (fstat(fd_, &file_stat) == -1)
|
||||||
|
throw SystemError(errno, "cannot get file attributes");
|
||||||
|
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size),
|
||||||
|
"return type of File::size is not large enough");
|
||||||
|
return file_stat.st_size;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t fmt::File::read(void *buffer, std::size_t count) {
|
std::size_t fmt::File::read(void *buffer, std::size_t count) {
|
||||||
RWResult result = 0;
|
RWResult result = 0;
|
||||||
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
||||||
|
5
posix.h
5
posix.h
@ -206,7 +206,7 @@ class File {
|
|||||||
File() FMT_NOEXCEPT(true) : fd_(-1) {}
|
File() FMT_NOEXCEPT(true) : fd_(-1) {}
|
||||||
|
|
||||||
// Opens a file and constructs a File object representing this file.
|
// Opens a file and constructs a File object representing this file.
|
||||||
File(const char *path, int oflag);
|
File(fmt::StringRef path, int oflag);
|
||||||
|
|
||||||
#if !FMT_USE_RVALUE_REFERENCES
|
#if !FMT_USE_RVALUE_REFERENCES
|
||||||
// Emulate a move constructor and a move assignment operator if rvalue
|
// Emulate a move constructor and a move assignment operator if rvalue
|
||||||
@ -277,6 +277,9 @@ class File {
|
|||||||
// Closes the file.
|
// Closes the file.
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
// Returns the file size.
|
||||||
|
fmt::LongLong size() const;
|
||||||
|
|
||||||
// Attempts to read count bytes from the file into the specified buffer.
|
// Attempts to read count bytes from the file into the specified buffer.
|
||||||
std::size_t read(void *buffer, std::size_t count);
|
std::size_t read(void *buffer, std::size_t count);
|
||||||
|
|
||||||
|
@ -194,6 +194,17 @@ TEST(FileTest, CloseNoRetry) {
|
|||||||
close_count = 0;
|
close_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FileTest, Size) {
|
||||||
|
BufferedFile bf("test", "w");
|
||||||
|
std::string content = "top secret, destroy before reading";
|
||||||
|
bf.print(content);
|
||||||
|
bf.close();
|
||||||
|
File f("test", File::RDONLY);
|
||||||
|
EXPECT_EQ(content.size(), f.size());
|
||||||
|
// TODO: test if size can handle large file sizes
|
||||||
|
// TODO: test FMT_STATIC_ASSERT
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FileTest, ReadRetry) {
|
TEST(FileTest, ReadRetry) {
|
||||||
File read_end, write_end;
|
File read_end, write_end;
|
||||||
File::pipe(read_end, write_end);
|
File::pipe(read_end, write_end);
|
||||||
|
Loading…
Reference in New Issue
Block a user