file_helper.cpp and filename_t fix
This commit is contained in:
		@@ -69,6 +69,15 @@
 | 
			
		||||
#define SPDLOG_FUNCTION __FUNCTION__
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
 | 
			
		||||
class formatter;
 | 
			
		||||
 | 
			
		||||
namespace sinks {
 | 
			
		||||
class sink;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
			
		||||
using filename_t = std::wstring;
 | 
			
		||||
#define SPDLOG_FILENAME_T(s) L##s
 | 
			
		||||
@@ -82,14 +91,6 @@ using filename_t = std::string;
 | 
			
		||||
#define SPDLOG_FILENAME_T(s) s
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
 | 
			
		||||
class formatter;
 | 
			
		||||
 | 
			
		||||
namespace sinks {
 | 
			
		||||
class sink;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using log_clock = std::chrono::system_clock;
 | 
			
		||||
using sink_ptr = std::shared_ptr<sinks::sink>;
 | 
			
		||||
using sinks_init_list = std::initializer_list<sink_ptr>;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,110 +5,36 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Helper class for file sinks.
 | 
			
		||||
// When failing to open a file, retry several times(5) with a delay interval(10 ms).
 | 
			
		||||
// Throw spdlog_ex exception on errors.
 | 
			
		||||
 | 
			
		||||
#include "spdlog/details/log_msg.h"
 | 
			
		||||
#include "spdlog/details/os.h"
 | 
			
		||||
 | 
			
		||||
#include <cerrno>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include "spdlog/common.h"
 | 
			
		||||
#include <tuple>
 | 
			
		||||
 | 
			
		||||
namespace spdlog {
 | 
			
		||||
namespace details {
 | 
			
		||||
 | 
			
		||||
// Helper class for file sinks.
 | 
			
		||||
// When failing to open a file, retry several times(5) with a delay interval(10 ms).
 | 
			
		||||
// Throw spdlog_ex exception on errors.
 | 
			
		||||
 | 
			
		||||
class file_helper
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    const int open_tries = 5;
 | 
			
		||||
    const int open_interval = 10;
 | 
			
		||||
 | 
			
		||||
    explicit file_helper() = default;
 | 
			
		||||
 | 
			
		||||
    file_helper(const file_helper &) = delete;
 | 
			
		||||
    file_helper &operator=(const file_helper &) = delete;
 | 
			
		||||
    ~file_helper();    
 | 
			
		||||
 | 
			
		||||
    ~file_helper()
 | 
			
		||||
    {
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void open(const filename_t &fname, bool truncate = false)
 | 
			
		||||
    {
 | 
			
		||||
        close();
 | 
			
		||||
        auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
 | 
			
		||||
        _filename = fname;
 | 
			
		||||
        for (int tries = 0; tries < open_tries; ++tries)
 | 
			
		||||
        {
 | 
			
		||||
            if (!os::fopen_s(&fd_, fname, mode))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            details::os::sleep_for_millis(open_interval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reopen(bool truncate)
 | 
			
		||||
    {
 | 
			
		||||
        if (_filename.empty())
 | 
			
		||||
        {
 | 
			
		||||
            throw spdlog_ex("Failed re opening file - was not opened before");
 | 
			
		||||
        }
 | 
			
		||||
        open(_filename, truncate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void flush()
 | 
			
		||||
    {
 | 
			
		||||
        std::fflush(fd_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void close()
 | 
			
		||||
    {
 | 
			
		||||
        if (fd_ != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            std::fclose(fd_);
 | 
			
		||||
            fd_ = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void write(const fmt::memory_buffer &buf)
 | 
			
		||||
    {
 | 
			
		||||
        size_t msg_size = buf.size();
 | 
			
		||||
        auto data = buf.data();
 | 
			
		||||
        if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
 | 
			
		||||
        {
 | 
			
		||||
            throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_t size() const
 | 
			
		||||
    {
 | 
			
		||||
        if (fd_ == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
 | 
			
		||||
        }
 | 
			
		||||
        return os::filesize(fd_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const filename_t &filename() const
 | 
			
		||||
    {
 | 
			
		||||
        return _filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static bool file_exists(const filename_t &fname)
 | 
			
		||||
    {
 | 
			
		||||
        return os::file_exists(fname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void open(const filename_t &fname, bool truncate = false);    
 | 
			
		||||
    void reopen(bool truncate);    
 | 
			
		||||
    void flush();    
 | 
			
		||||
    void close();    
 | 
			
		||||
    void write(const fmt::memory_buffer &buf);
 | 
			
		||||
    size_t size() const;    
 | 
			
		||||
    const filename_t &filename() const;
 | 
			
		||||
    static bool file_exists(const filename_t &fname);
 | 
			
		||||
    
 | 
			
		||||
    //
 | 
			
		||||
    // return file path and its extension:
 | 
			
		||||
    //
 | 
			
		||||
@@ -122,27 +48,7 @@ public:
 | 
			
		||||
    // ".mylog" => (".mylog". "")
 | 
			
		||||
    // "my_folder/.mylog" => ("my_folder/.mylog", "")
 | 
			
		||||
    // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
 | 
			
		||||
    static std::tuple<filename_t, filename_t> split_by_extension(const spdlog::filename_t &fname)
 | 
			
		||||
    {
 | 
			
		||||
        auto ext_index = fname.rfind('.');
 | 
			
		||||
 | 
			
		||||
        // no valid extension found - return whole path and empty string as
 | 
			
		||||
        // extension
 | 
			
		||||
        if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
 | 
			
		||||
        {
 | 
			
		||||
            return std::make_tuple(fname, spdlog::filename_t());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
 | 
			
		||||
        auto folder_index = fname.rfind(details::os::folder_sep);
 | 
			
		||||
        if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
 | 
			
		||||
        {
 | 
			
		||||
            return std::make_tuple(fname, spdlog::filename_t());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // finally - return a valid base and extension tuple
 | 
			
		||||
        return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
 | 
			
		||||
    }
 | 
			
		||||
    static std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::FILE *fd_{nullptr};
 | 
			
		||||
@@ -150,3 +56,7 @@ private:
 | 
			
		||||
};
 | 
			
		||||
} // namespace details
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
#ifdef  SPDLOG_HEADER_ONLY
 | 
			
		||||
#include "../../../src/file_helper.cpp"
 | 
			
		||||
#endif // ! SPDLOG_HEADER_ONLY
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user