qxLib
file_logger_stream_fopen.inl
Go to the documentation of this file.
1 /**
2 
3  @file file_logger_stream_fopen.inl
4  @author Khrapov
5  @date 15.01.2026
6  @copyright © Nick Khrapov, 2026. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 
14  const config& streamConfig,
15  unit<size_t, units::data> bufferSize) noexcept
16  : base_file_logger_stream(streamConfig)
17 {
18  std::ios_base::sync_with_stdio(false);
19 
20  const char* pszOpeningMode = streamConfig.eLogFilePolicy == log_file_policy::clear_then_uppend ? "wb" : "ab";
21 
22  const std::filesystem::path path =
23  create_folder_and_get_log_file_path(streamConfig.eLogFilePolicy, streamConfig.svFileName);
24 
25  QX_DISABLE_MSVC_WARNINGS(4996);
26  m_pFile = std::fopen(path.generic_string().c_str(), pszOpeningMode);
27  if (!m_pFile)
28  {
29  string sLastError = to_string(std::strerror(errno));
30  details::get_cerr<char_type>::get() << QXT("Can't open log file: ") << path << QXT(", error: ") << sLastError;
31  return;
32  }
33  QX_RESTORE_MSVC_WARNINGS(4996);
34 
35  if (bufferSize.value > 0)
36  {
37  const unit<size_t, units::data> bytes = convert(bufferSize).to(units::data::bytes);
38  m_Buffer.resize(bytes.value);
39  std::setvbuf(m_pFile, m_Buffer.data(), _IOFBF, m_Buffer.size());
40  }
41 }
42 
44  : base_file_logger_stream(std::move(other))
45 {
46  std::swap(m_Buffer, other.m_Buffer);
47  std::swap(m_pFile, other.m_pFile);
48 }
49 
50 inline file_logger_stream_fopen::~file_logger_stream_fopen()
51 {
52  if (m_pFile)
53  {
54  std::fclose(m_pFile);
55  m_pFile = nullptr;
56  }
57 }
58 
60  const category& category,
61  verbosity eVerbosity,
62  std::thread::id threadId,
63  std::chrono::system_clock::time_point messageTime,
64  string_view svFile,
65  string_view svFunction,
66  int nLine,
67  string_view svMessage)
68 {
69  if (m_pFile)
70  {
71 #if QX_WIN || QX_CONF_USE_CHAR
72  std::fwrite(svMessage.data(), sizeof(char_type), svMessage.size(), m_pFile);
73 #else
74  std::array<char16_t, 2048> chunk;
75 
76  const char_type* pData = svMessage.data();
77  size_t nCharsRemaining = svMessage.size();
78 
79  while (nCharsRemaining > 0)
80  {
81  size_t nCharsToTake = std::min(nCharsRemaining, chunk.size());
82  for (size_t i = 0; i < nCharsToTake; ++i)
83  {
84  chunk[i] = static_cast<char16_t>(static_cast<char16_t>(pData[i]) & 0xFFFFu);
85  }
86 
87  std::fwrite(chunk.data(), sizeof(char16_t), nCharsToTake, m_pFile);
88 
89  pData += nCharsToTake;
90  nCharsRemaining -= nCharsToTake;
91  }
92 #endif
93  }
94 }
95 
97 {
98  if (m_pFile)
99  std::fflush(m_pFile);
100 }
101 
102 } // namespace qx
Base class for all file logger streams.
A category is a class that identifies a particular piece of code. This code can be located in differe...
Definition: category.h:59
A conversion class.
Definition: base.h:77
FILE* based file logger stream.
virtual void do_flush() override
Flush the stream.
virtual void do_log(const category &category, verbosity eVerbosity, std::thread::id threadId, std::chrono::system_clock::time_point messageTime, string_view svFile, string_view svFunction, int nLine, string_view svMessage) override
Proceed stream logging.
file_logger_stream_fopen(const config &streamConfig=config(), unit< size_t, units::data > bufferSize={ 8192 *sizeof(char_type), units::data::bytes }) noexcept
file_logger_stream_fopen object constructor
void to_string(string &out, cstring_view stringView, const std::locale &locale=std::locale())
Convert a char string to common string type.
Definition: base.h:52