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 | #include <spdlog/common.h> |
7 | #include <spdlog/details/log_msg.h> |
8 | #include <spdlog/details/os.h> |
9 | #include <spdlog/formatter.h> |
10 | |
11 | #include <chrono> |
12 | #include <ctime> |
13 | #include <memory> |
14 | |
15 | #include <string> |
16 | #include <vector> |
17 | #include <unordered_map> |
18 | |
19 | namespace spdlog { |
20 | namespace details { |
21 | |
22 | // padding information. |
23 | struct padding_info |
24 | { |
25 | enum class pad_side |
26 | { |
27 | left, |
28 | right, |
29 | center |
30 | }; |
31 | |
32 | padding_info() = default; |
33 | padding_info(size_t width, padding_info::pad_side side, bool truncate) |
34 | : width_(width) |
35 | , side_(side) |
36 | , truncate_(truncate) |
37 | , enabled_(true) |
38 | {} |
39 | |
40 | bool enabled() const |
41 | { |
42 | return enabled_; |
43 | } |
44 | size_t width_ = 0; |
45 | pad_side side_ = pad_side::left; |
46 | bool truncate_ = false; |
47 | bool enabled_ = false; |
48 | }; |
49 | |
50 | class SPDLOG_API flag_formatter |
51 | { |
52 | public: |
53 | explicit flag_formatter(padding_info padinfo) |
54 | : padinfo_(padinfo) |
55 | {} |
56 | flag_formatter() = default; |
57 | virtual ~flag_formatter() = default; |
58 | virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0; |
59 | |
60 | protected: |
61 | padding_info padinfo_; |
62 | }; |
63 | |
64 | } // namespace details |
65 | |
66 | class SPDLOG_API custom_flag_formatter : public details::flag_formatter |
67 | { |
68 | public: |
69 | virtual std::unique_ptr<custom_flag_formatter> clone() const = 0; |
70 | |
71 | void set_padding_info(const details::padding_info &padding) |
72 | { |
73 | flag_formatter::padinfo_ = padding; |
74 | } |
75 | }; |
76 | |
77 | class SPDLOG_API pattern_formatter final : public formatter |
78 | { |
79 | public: |
80 | using custom_flags = std::unordered_map<char, std::unique_ptr<custom_flag_formatter>>; |
81 | |
82 | explicit pattern_formatter(std::string pattern, pattern_time_type time_type = pattern_time_type::local, |
83 | std::string eol = spdlog::details::os::default_eol, custom_flags custom_user_flags = custom_flags()); |
84 | |
85 | // use default pattern is not given |
86 | explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); |
87 | |
88 | pattern_formatter(const pattern_formatter &other) = delete; |
89 | pattern_formatter &operator=(const pattern_formatter &other) = delete; |
90 | |
91 | std::unique_ptr<formatter> clone() const override; |
92 | void format(const details::log_msg &msg, memory_buf_t &dest) override; |
93 | |
94 | template<typename T, typename... Args> |
95 | pattern_formatter &add_flag(char flag, Args &&... args) |
96 | { |
97 | custom_handlers_[flag] = details::make_unique<T>(std::forward<Args>(args)...); |
98 | return *this; |
99 | } |
100 | void set_pattern(std::string pattern); |
101 | void need_localtime(bool need = true); |
102 | |
103 | private: |
104 | std::string pattern_; |
105 | std::string eol_; |
106 | pattern_time_type pattern_time_type_; |
107 | bool need_localtime_; |
108 | std::tm cached_tm_; |
109 | std::chrono::seconds last_log_secs_; |
110 | std::vector<std::unique_ptr<details::flag_formatter>> formatters_; |
111 | custom_flags custom_handlers_; |
112 | |
113 | std::tm get_time_(const details::log_msg &msg); |
114 | template<typename Padder> |
115 | void handle_flag_(char flag, details::padding_info padding); |
116 | |
117 | // Extract given pad spec (e.g. %8X) |
118 | // Advance the given it pass the end of the padding spec found (if any) |
119 | // Return padding. |
120 | static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); |
121 | |
122 | void compile_pattern_(const std::string &pattern); |
123 | }; |
124 | } // namespace spdlog |
125 | |
126 | #ifdef SPDLOG_HEADER_ONLY |
127 | # include "pattern_formatter-inl.h" |
128 | #endif |
129 | |