Agora  1.2.0
Agora project
file_helper-inl.h
Go to the documentation of this file.
1 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
3 
4 #pragma once
5 
6 #ifndef SPDLOG_HEADER_ONLY
8 #endif
9 
10 #include <spdlog/details/os.h>
11 #include <spdlog/common.h>
12 
13 #include <cerrno>
14 #include <chrono>
15 #include <cstdio>
16 #include <string>
17 #include <thread>
18 #include <tuple>
19 
20 namespace spdlog {
21 namespace details {
22 
24  : event_handlers_(event_handlers)
25 {}
26 
28 {
29  close();
30 }
31 
32 SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
33 {
34  close();
35  filename_ = fname;
36 
37  auto *mode = SPDLOG_FILENAME_T("ab");
38  auto *trunc_mode = SPDLOG_FILENAME_T("wb");
39 
41  {
43  }
44  for (int tries = 0; tries < open_tries_; ++tries)
45  {
46  // create containing folder if not exists already.
48  if (truncate)
49  {
50  // Truncate by opening-and-closing a tmp file in "wb" mode, always
51  // opening the actual log-we-write-to in "ab" mode, since that
52  // interacts more politely with eternal processes that might
53  // rotate/truncate the file underneath us.
54  std::FILE *tmp;
55  if (os::fopen_s(&tmp, fname, trunc_mode))
56  {
57  continue;
58  }
59  std::fclose(tmp);
60  }
61  if (!os::fopen_s(&fd_, fname, mode))
62  {
64  {
66  }
67  return;
68  }
69 
71  }
72 
73  throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno);
74 }
75 
77 {
78  if (filename_.empty())
79  {
80  throw_spdlog_ex("Failed re opening file - was not opened before");
81  }
82  this->open(filename_, truncate);
83 }
84 
86 {
87  if (std::fflush(fd_) != 0)
88  {
89  throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
90  }
91 }
92 
94 {
95  if (fd_ != nullptr)
96  {
98  {
100  }
101 
102  std::fclose(fd_);
103  fd_ = nullptr;
104 
106  {
108  }
109  }
110 }
111 
113 {
114  size_t msg_size = buf.size();
115  auto data = buf.data();
116  if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
117  {
118  throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
119  }
120 }
121 
123 {
124  if (fd_ == nullptr)
125  {
126  throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
127  }
128  return os::filesize(fd_);
129 }
130 
132 {
133  return filename_;
134 }
135 
136 //
137 // return file path and its extension:
138 //
139 // "mylog.txt" => ("mylog", ".txt")
140 // "mylog" => ("mylog", "")
141 // "mylog." => ("mylog.", "")
142 // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
143 //
144 // the starting dot in filenames is ignored (hidden files):
145 //
146 // ".mylog" => (".mylog". "")
147 // "my_folder/.mylog" => ("my_folder/.mylog", "")
148 // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
149 SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(const filename_t &fname)
150 {
151  auto ext_index = fname.rfind('.');
152 
153  // no valid extension found - return whole path and empty string as
154  // extension
155  if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
156  {
157  return std::make_tuple(fname, filename_t());
158  }
159 
160  // treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
161  auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
162  if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
163  {
164  return std::make_tuple(fname, filename_t());
165  }
166 
167  // finally - return a valid base and extension tuple
168  return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
169 }
170 
171 } // namespace details
172 } // namespace spdlog
file_helper.h
spdlog::details::file_helper::size
size_t size() const
Definition: file_helper-inl.h:122
spdlog::file_event_handlers
Definition: common.h:308
spdlog::details::file_helper::open
void open(const filename_t &fname, bool truncate=false)
Definition: file_helper-inl.h:32
spdlog::details::file_helper::split_by_extension
static std::tuple< filename_t, filename_t > split_by_extension(const filename_t &fname)
Definition: file_helper-inl.h:149
spdlog::details::os::sleep_for_millis
SPDLOG_INLINE void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT
Definition: os-inl.h:376
mm_gui.mode
string mode
Definition: mm_gui.py:105
fmt::v8::detail::buffer::size
constexpr auto size() const -> size_t
Definition: core.h:820
spdlog::details::file_helper::reopen
void reopen(bool truncate)
Definition: file_helper-inl.h:76
spdlog::file_event_handlers::before_close
std::function< void(const filename_t &filename, std::FILE *file_stream)> before_close
Definition: common.h:312
fclose
fclose(fileID)
spdlog::details::file_helper::file_helper
file_helper()=default
spdlog::details::os::fopen_s
SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode)
Definition: os-inl.h:123
fmt::v8::basic_memory_buffer
Definition: format.h:677
spdlog::details::file_helper::close
void close()
Definition: file_helper-inl.h:93
spdlog::details::os::create_dir
SPDLOG_INLINE bool create_dir(const filename_t &path)
Definition: os-inl.h:545
spdlog
Definition: async.h:25
spdlog::details::file_helper::fd_
std::FILE * fd_
Definition: file_helper.h:52
spdlog::throw_spdlog_ex
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition: common-inl.h:72
spdlog::details::file_helper::filename
const filename_t & filename() const
Definition: file_helper-inl.h:131
spdlog::details::os::filename_to_str
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
Definition: os-inl.h:398
SPDLOG_INLINE
#define SPDLOG_INLINE
Definition: common.h:42
os.h
spdlog::details::os::filesize
SPDLOG_INLINE size_t filesize(FILE *f)
Definition: os-inl.h:209
spdlog::details::file_helper::~file_helper
~file_helper()
Definition: file_helper-inl.h:27
spdlog::details::file_helper::write
void write(const memory_buf_t &buf)
Definition: file_helper-inl.h:112
spdlog::details::os::folder_seps_filename
static const SPDLOG_CONSTEXPR filename_t::value_type folder_seps_filename[]
Definition: os.h:44
spdlog::details::file_helper::filename_
filename_t filename_
Definition: file_helper.h:53
extract_version.data
dictionary data
Definition: extract_version.py:8
fmt::v8::detail::buffer::data
auto data() -> T *
Definition: core.h:826
SPDLOG_FILENAME_T
#define SPDLOG_FILENAME_T(s)
Definition: common.h:123
spdlog::details::file_helper::flush
void flush()
Definition: file_helper-inl.h:85
spdlog::details::file_helper::open_tries_
const int open_tries_
Definition: file_helper.h:50
spdlog::file_event_handlers::after_open
std::function< void(const filename_t &filename, std::FILE *file_stream)> after_open
Definition: common.h:311
common.h
spdlog::file_event_handlers::after_close
std::function< void(const filename_t &filename)> after_close
Definition: common.h:313
fwrite
fwrite(fileID, pilot_f, 'float')
spdlog::file_event_handlers::before_open
std::function< void(const filename_t &filename)> before_open
Definition: common.h:310
spdlog::details::file_helper::event_handlers_
file_event_handlers event_handlers_
Definition: file_helper.h:54
spdlog::filename_t
std::string filename_t
Definition: common.h:122
spdlog::details::file_helper::open_interval_
const unsigned int open_interval_
Definition: file_helper.h:51
spdlog::details::os::dir_name
SPDLOG_INLINE filename_t dir_name(const filename_t &path)
Definition: os-inl.h:584