File indexing completed on 2025-01-18 10:12:41
0001
0002
0003
0004 #pragma once
0005
0006 #ifndef SPDLOG_HEADER_ONLY
0007 # include <spdlog/details/file_helper.h>
0008 #endif
0009
0010 #include <spdlog/details/os.h>
0011 #include <spdlog/common.h>
0012
0013 #include <cerrno>
0014 #include <chrono>
0015 #include <cstdio>
0016 #include <string>
0017 #include <thread>
0018 #include <tuple>
0019
0020 namespace spdlog {
0021 namespace details {
0022
0023 SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers)
0024 : event_handlers_(event_handlers)
0025 {}
0026
0027 SPDLOG_INLINE file_helper::~file_helper()
0028 {
0029 close();
0030 }
0031
0032 SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
0033 {
0034 close();
0035 filename_ = fname;
0036
0037 auto *mode = SPDLOG_FILENAME_T("ab");
0038 auto *trunc_mode = SPDLOG_FILENAME_T("wb");
0039
0040 if (event_handlers_.before_open)
0041 {
0042 event_handlers_.before_open(filename_);
0043 }
0044 for (int tries = 0; tries < open_tries_; ++tries)
0045 {
0046
0047 os::create_dir(os::dir_name(fname));
0048 if (truncate)
0049 {
0050
0051
0052
0053
0054 std::FILE *tmp;
0055 if (os::fopen_s(&tmp, fname, trunc_mode))
0056 {
0057 continue;
0058 }
0059 std::fclose(tmp);
0060 }
0061 if (!os::fopen_s(&fd_, fname, mode))
0062 {
0063 if (event_handlers_.after_open)
0064 {
0065 event_handlers_.after_open(filename_, fd_);
0066 }
0067 return;
0068 }
0069
0070 details::os::sleep_for_millis(open_interval_);
0071 }
0072
0073 throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno);
0074 }
0075
0076 SPDLOG_INLINE void file_helper::reopen(bool truncate)
0077 {
0078 if (filename_.empty())
0079 {
0080 throw_spdlog_ex("Failed re opening file - was not opened before");
0081 }
0082 this->open(filename_, truncate);
0083 }
0084
0085 SPDLOG_INLINE void file_helper::flush()
0086 {
0087 if (std::fflush(fd_) != 0)
0088 {
0089 throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
0090 }
0091 }
0092
0093 SPDLOG_INLINE void file_helper::close()
0094 {
0095 if (fd_ != nullptr)
0096 {
0097 if (event_handlers_.before_close)
0098 {
0099 event_handlers_.before_close(filename_, fd_);
0100 }
0101
0102 std::fclose(fd_);
0103 fd_ = nullptr;
0104
0105 if (event_handlers_.after_close)
0106 {
0107 event_handlers_.after_close(filename_);
0108 }
0109 }
0110 }
0111
0112 SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf)
0113 {
0114 size_t msg_size = buf.size();
0115 auto data = buf.data();
0116 if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
0117 {
0118 throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
0119 }
0120 }
0121
0122 SPDLOG_INLINE size_t file_helper::size() const
0123 {
0124 if (fd_ == nullptr)
0125 {
0126 throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
0127 }
0128 return os::filesize(fd_);
0129 }
0130
0131 SPDLOG_INLINE const filename_t &file_helper::filename() const
0132 {
0133 return filename_;
0134 }
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(const filename_t &fname)
0150 {
0151 auto ext_index = fname.rfind('.');
0152
0153
0154
0155 if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
0156 {
0157 return std::make_tuple(fname, filename_t());
0158 }
0159
0160
0161 auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
0162 if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
0163 {
0164 return std::make_tuple(fname, filename_t());
0165 }
0166
0167
0168 return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
0169 }
0170
0171 }
0172 }