1 | #include "caffe2/serialize/file_adapter.h" |
2 | #include <c10/util/Exception.h> |
3 | #include <cerrno> |
4 | #include <cstdio> |
5 | #include <string> |
6 | #include "caffe2/core/common.h" |
7 | |
8 | namespace caffe2 { |
9 | namespace serialize { |
10 | |
11 | FileAdapter::RAIIFile::RAIIFile(const std::string& file_name) { |
12 | fp_ = fopen(file_name.c_str(), "rb" ); |
13 | if (fp_ == nullptr) { |
14 | char buf[1024]; |
15 | buf[0] = '\0'; |
16 | #if defined(_WIN32) && (defined(__MINGW32__) || defined(_MSC_VER)) |
17 | strerror_s(buf, sizeof(buf), errno); |
18 | #else |
19 | strerror_r(errno, buf, sizeof(buf)); |
20 | #endif |
21 | AT_ERROR( |
22 | "open file failed because of errno " , |
23 | errno, |
24 | " on fopen: " , |
25 | buf, |
26 | ", file path: " , |
27 | file_name); |
28 | } |
29 | } |
30 | |
31 | FileAdapter::RAIIFile::~RAIIFile() { |
32 | if (fp_ != nullptr) { |
33 | fclose(fp_); |
34 | } |
35 | } |
36 | |
37 | // FileAdapter directly calls C file API. |
38 | FileAdapter::FileAdapter(const std::string& file_name): file_(file_name) { |
39 | const int fseek_ret = fseek(file_.fp_, 0L, SEEK_END); |
40 | TORCH_CHECK(fseek_ret == 0, "fseek returned " , fseek_ret); |
41 | #if defined(_MSC_VER) |
42 | const int64_t ftell_ret = _ftelli64(file_.fp_); |
43 | #else |
44 | const off_t ftell_ret = ftello(file_.fp_); |
45 | #endif |
46 | TORCH_CHECK(ftell_ret != -1L, "ftell returned " , ftell_ret); |
47 | size_ = ftell_ret; |
48 | rewind(file_.fp_); |
49 | } |
50 | |
51 | size_t FileAdapter::size() const { |
52 | return size_; |
53 | } |
54 | |
55 | size_t FileAdapter::read(uint64_t pos, void* buf, size_t n, const char* what) |
56 | const { |
57 | // Ensure that pos doesn't exceed size_. |
58 | pos = std::min(pos, size_); |
59 | // If pos doesn't exceed size_, then size_ - pos can never be negative (in |
60 | // signed math) or since these are unsigned values, a very large value. |
61 | // Clamp 'n' to the smaller of 'size_ - pos' and 'n' itself. i.e. if the |
62 | // user requested to read beyond the end of the file, we clamp to just the |
63 | // end of the file. |
64 | n = std::min(static_cast<size_t>(size_ - pos), n); |
65 | #if defined(_MSC_VER) |
66 | const int fseek_ret = _fseeki64(file_.fp_, pos, SEEK_SET); |
67 | #else |
68 | const int fseek_ret = fseeko(file_.fp_, pos, SEEK_SET); |
69 | #endif |
70 | TORCH_CHECK( |
71 | fseek_ret == 0, |
72 | "fseek returned " , |
73 | fseek_ret, |
74 | ", context: " , |
75 | what); |
76 | return fread(buf, 1, n, file_.fp_); |
77 | } |
78 | |
79 | FileAdapter::~FileAdapter() = default; |
80 | |
81 | } // namespace serialize |
82 | } // namespace caffe2 |
83 | |