1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef LOG_H
17 #define LOG_H
18
19 #include <array>
20 #include <utility>
21 #include <string_view>
22 #include <cinttypes>
23 #include <cstdio>
24 #include <hilog/log_c.h>
25
26 template<size_t N>
CountPercent(const char (& str)[N])27 constexpr auto CountPercent(const char(&str)[N])
28 {
29 uint32_t cntOfPercentSign = 0;
30 std::array<bool, N> isPercentSign{};
31 for (size_t i = 0; i < N; i++) {
32 if (str[i] == '%') {
33 cntOfPercentSign++;
34 isPercentSign[i] = true;
35 } else {
36 isPercentSign[i] = false;
37 }
38 }
39 for (size_t i = 1; i < N; i++) {
40 if (isPercentSign[i - 1] && isPercentSign[i]) {
41 cntOfPercentSign -= 2; // 2 is length of %%
42 isPercentSign[i - 1] = false;
43 isPercentSign[i] = false;
44 }
45 }
46 return std::make_pair(cntOfPercentSign, isPercentSign);
47 }
48
49 template<uint32_t cntOfPercentSign, size_t N>
AddPublic(const char (& str)[N],const std::array<bool,N> & isPercentSign)50 constexpr auto AddPublic(const char(&str)[N], const std::array<bool, N> &isPercentSign)
51 {
52 constexpr std::string_view pub = "{public}";
53 std::array<char, N + cntOfPercentSign * pub.size()> newStr{};
54 for (size_t i = 0, j = 0; i < N; i++, j++) {
55 newStr[j] = str[i];
56 if (isPercentSign[i]) {
57 for (size_t k = 0; k < pub.size(); k++) {
58 newStr[j + 1 + k] = pub[k];
59 }
60 j += pub.size();
61 }
62 }
63 return newStr;
64 }
65
66 inline constexpr unsigned int HCODEC_DOMAIN = 0xD002B32;
67 inline constexpr const char* HCODEC_TAG = "HCODEC";
68 #ifdef HILOG_FMTID
69 #define RE_FORMAT(level, s, ...) do { \
70 constexpr auto pair = CountPercent(s); \
71 constexpr HILOG_FMT_IN_SECTION static auto newStr = AddPublic<pair.first>(s, pair.second); \
72 (void)HiLogPrintDictNew(LOG_CORE, level, HCODEC_DOMAIN, HCODEC_TAG, \
73 HILOG_UUID, HILOG_FMT_OFFSET(newStr.data()), newStr.data(), ##__VA_ARGS__); \
74 } while (0)
75 #else
76 #define RE_FORMAT(level, s, ...) do { \
77 constexpr auto pair = CountPercent(s); \
78 constexpr auto newStr = AddPublic<pair.first>(s, pair.second); \
79 (void)HiLogPrint(LOG_CORE, level, HCODEC_DOMAIN, HCODEC_TAG, newStr.data(), ##__VA_ARGS__); \
80 } while (0)
81 #endif
82
StrLevel(LogLevel level)83 inline constexpr const char* StrLevel(LogLevel level)
84 {
85 switch (level) {
86 case LOG_ERROR:
87 return "E";
88 case LOG_WARN:
89 return "W";
90 case LOG_INFO:
91 return "I";
92 case LOG_DEBUG:
93 return "D";
94 default:
95 return "";
96 }
97 }
98
99 #define PLOGI(...) RE_FORMAT(LOG_INFO, __VA_ARGS__)
100
101 #define LOG(level, s, ...) RE_FORMAT(level, "[%s %d] " s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
102 #define LOGE(...) LOG(LOG_ERROR, __VA_ARGS__)
103 #define LOGW(...) LOG(LOG_WARN, __VA_ARGS__)
104 #define LOGI(...) LOG(LOG_INFO, __VA_ARGS__)
105 #define LOGD(...) LOG(LOG_DEBUG, __VA_ARGS__)
106
107 // for test
108 #define TLOG(level, s, ...) do { \
109 RE_FORMAT(level, "[%s %d] " s, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
110 printf("%s: [%s %d] " s "\n", StrLevel(level), __FUNCTION__, __LINE__, ##__VA_ARGS__); \
111 } while (0)
112 #define TLOGE(...) TLOG(LOG_ERROR, __VA_ARGS__)
113 #define TLOGW(...) TLOG(LOG_WARN, __VA_ARGS__)
114 #define TLOGI(...) TLOG(LOG_INFO, __VA_ARGS__)
115 #define TLOGD(...) TLOG(LOG_DEBUG, __VA_ARGS__)
116
117 // for HCodec
118 #define HLOG(level, s, ...) RE_FORMAT(level, "%s[%s][%s %d] " s, \
119 compUniqueStr_.c_str(), currState_->GetName().c_str(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
120 #define HLOGE(...) HLOG(LOG_ERROR, __VA_ARGS__)
121 #define HLOGW(...) HLOG(LOG_WARN, __VA_ARGS__)
122 #define HLOGI(...) HLOG(LOG_INFO, __VA_ARGS__)
123 #define HLOGD(...) HLOG(LOG_DEBUG, __VA_ARGS__)
124
125 // for HCodec inner state
126 #define SLOG(level, s, ...) RE_FORMAT(level, "%s[%s][%s %d] " s, \
127 codec_->compUniqueStr_.c_str(), stateName_.c_str(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
128 #define SLOGE(...) SLOG(LOG_ERROR, __VA_ARGS__)
129 #define SLOGW(...) SLOG(LOG_WARN, __VA_ARGS__)
130 #define SLOGI(...) SLOG(LOG_INFO, __VA_ARGS__)
131 #define SLOGD(...) SLOG(LOG_DEBUG, __VA_ARGS__)
132
133 #define IF_TRUE_RETURN_VAL(cond, val) \
134 do { \
135 if (cond) { \
136 return val; \
137 } \
138 } while (0)
139 #define IF_TRUE_RETURN_VAL_WITH_MSG(cond, val, msg, ...) \
140 do { \
141 if (cond) { \
142 LOGE(msg, ##__VA_ARGS__); \
143 return val; \
144 } \
145 } while (0)
146 #define IF_TRUE_RETURN_VOID(cond) \
147 do { \
148 if (cond) { \
149 return; \
150 } \
151 } while (0)
152 #define IF_TRUE_RETURN_VOID_WITH_MSG(cond, msg, ...) \
153 do { \
154 if (cond) { \
155 LOGE(msg, ##__VA_ARGS__); \
156 return; \
157 } \
158 } while (0)
159
160 #endif