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