| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| #include "hwy/detect_compiler_arch.h" |
| |
| |
| #if !HWY_OS_WIN |
|
|
| |
| #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 700 |
| #undef _XOPEN_SOURCE |
| #define _XOPEN_SOURCE 700 |
| #endif |
| #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809 |
| #define _POSIX_C_SOURCE 200809 |
| #endif |
|
|
| |
| #undef _FILE_OFFSET_BITS |
| #define _FILE_OFFSET_BITS 64 |
|
|
| #include <fcntl.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <sys/stat.h> |
| #include <unistd.h> |
|
|
| #include <memory> |
|
|
| #include "compression/io.h" |
| #include "hwy/base.h" |
|
|
| namespace gcpp { |
|
|
| class FilePosix : public File { |
| int fd_ = 0; |
|
|
| public: |
| explicit FilePosix(int fd) : fd_(fd) { HWY_ASSERT(fd > 0); } |
| ~FilePosix() override { |
| if (fd_ != 0) { |
| HWY_ASSERT(close(fd_) != -1); |
| } |
| } |
|
|
| uint64_t FileSize() const override { |
| static_assert(sizeof(off_t) == 8, "64-bit off_t required"); |
| const off_t size = lseek(fd_, 0, SEEK_END); |
| if (size < 0) { |
| return 0; |
| } |
| return static_cast<uint64_t>(size); |
| } |
|
|
| bool Read(uint64_t offset, uint64_t size, void* to) const override { |
| uint8_t* bytes = reinterpret_cast<uint8_t*>(to); |
| uint64_t pos = 0; |
| for (;;) { |
| |
| const auto bytes_read = pread(fd_, bytes + pos, size - pos, offset + pos); |
| if (bytes_read <= 0) break; |
| pos += bytes_read; |
| HWY_ASSERT(pos <= size); |
| if (pos == size) break; |
| } |
| return pos == size; |
| } |
|
|
| bool Write(const void* from, uint64_t size, uint64_t offset) override { |
| const uint8_t* bytes = reinterpret_cast<const uint8_t*>(from); |
| uint64_t pos = 0; |
| for (;;) { |
| const auto bytes_written = |
| pwrite(fd_, bytes + pos, size - pos, offset + pos); |
| if (bytes_written <= 0) break; |
| pos += bytes_written; |
| HWY_ASSERT(pos <= size); |
| if (pos == size) break; |
| } |
| return pos == size; |
| } |
| }; |
|
|
| HWY_MAYBE_UNUSED extern std::unique_ptr<File> OpenFileGoogle( |
| const Path& filename, const char* mode); |
|
|
| std::unique_ptr<File> OpenFileOrNull(const Path& filename, const char* mode) { |
| std::unique_ptr<File> file; |
| if (file) return file; |
|
|
| const bool is_read = mode[0] != 'w'; |
| const int flags = is_read ? O_RDONLY : O_CREAT | O_RDWR | O_TRUNC; |
| const int fd = open(filename.path.c_str(), flags, 0644); |
| if (fd < 0) return file; |
|
|
| #if HWY_OS_LINUX && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21) |
| if (is_read) { |
| |
| (void)posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL); |
| } |
| #endif |
|
|
| return std::make_unique<FilePosix>(fd); |
| } |
|
|
| } |
| #endif |
|
|