1 /*
2 * Copyright (c) 2022 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 #include "hilog_module.h"
17 #include "hilog_wrapper.h"
18 #include "securec.h"
19
20 namespace OHOS {
21 namespace ACELite {
22 namespace {
23 #define DEFAULT_LOG_TYPE LOG_TYPE_MIN
24 // log content prefix:"%c %05X/%s: " %05X->domain %s->tag
25 static const int32_t DOMAIN_LEN = 5;
26 static const int32_t FIX_LEN = 5;
27 static const int32_t MIN_DOMAIN = 0x0;
28 static const int32_t MAX_DOMAIN = 0xFFFF;
29 static const int32_t MAX_TAG = 32;
30 static const int32_t MAX_FORMAT = 1024;
31 static const int32_t MIN_NUMBER = 3;
32 static const int32_t MAX_NUMBER = 16;
33 static const int32_t PUBLIC_LEN = 6;
34 static const int32_t PRIVATE_LEN = 7;
35 static const int32_t PROPERTY_POS = 2;
36 static const char PRIV_STR[10] = "<private>";
37 static const int32_t FIRST = 0;
38 static const int32_t SECOND = 1;
39 static const int32_t THIRD = 2;
40 static const int32_t FOURTH = 3;
41 static const int32_t FIFTH = 4;
42 }
43
ParseLogContent(const HilogString * formatStr,const HilogVector * params,HilogString * logContent)44 void HilogModule::ParseLogContent(const HilogString *formatStr, const HilogVector *params, HilogString *logContent)
45 {
46 if (formatStr == nullptr || params == nullptr || logContent == nullptr) {
47 return;
48 }
49 size_t size = HilogVector::Size(params);
50 if (size == 0) {
51 HilogString::Puts(HilogString::Get(formatStr), logContent);
52 return;
53 }
54 char *format = HilogString::Get(formatStr);
55 size_t len = HilogString::Length(formatStr);
56 size_t pos = 0;
57 size_t count = 0;
58
59 for (; pos < len; ++pos) {
60 bool showPriv = true;
61 if (count > size) {
62 break;
63 }
64 if (format[pos] != '%') {
65 HilogString::Putc(format[pos], logContent);
66 continue;
67 }
68
69 if (((pos + PUBLIC_LEN + PROPERTY_POS) < len) &&
70 (strncmp(format + pos + PROPERTY_POS, "public", PUBLIC_LEN) == 0)) {
71 pos += (PUBLIC_LEN + PROPERTY_POS);
72 showPriv = false;
73 } else if (((pos + PRIVATE_LEN + PROPERTY_POS) < len) &&
74 (strncmp(format + pos + PROPERTY_POS, "private", PRIVATE_LEN) == 0)) {
75 pos += (PRIVATE_LEN + PROPERTY_POS);
76 }
77
78 if (pos + 1 >= len) {
79 break;
80 }
81 AddLogContentOutParams outParams = {
82 .pos = &pos,
83 .count = &count,
84 .logContent = logContent,
85 };
86 AddLogContent(format, params, showPriv, &outParams);
87 }
88 if (pos < len) {
89 HilogString::Puts(format + pos, logContent, len - pos);
90 }
91 return;
92 }
93
AddLogContent(const char * format,const HilogVector * params,bool showPriv,const AddLogContentOutParams * outParams)94 void HilogModule::AddLogContent(const char *format, const HilogVector *params, bool showPriv,
95 const AddLogContentOutParams *outParams)
96 {
97 if (format == nullptr || outParams == nullptr || params == nullptr || outParams->pos == nullptr ||
98 outParams->count == nullptr || outParams->logContent == nullptr) {
99 return;
100 }
101 if ((*(outParams->pos) + 1) >= strlen(format)) {
102 return;
103 }
104
105 switch (format[*(outParams->pos) + 1]) {
106 case 'i':
107 case 'd':
108 if (HilogVector::GetType(params, *(outParams->count)) == INT_TYPE) {
109 HilogString::Puts(
110 showPriv ? PRIV_STR : HilogVector::GetStr(params, *(outParams->count)), outParams->logContent);
111 }
112 (*(outParams->count))++;
113 ++(*(outParams->pos));
114 break;
115 case 's':
116 if (HilogVector::GetType(params, *(outParams->count)) == STRING_TYPE) {
117 HilogString::Puts(
118 showPriv ? PRIV_STR : HilogVector::GetStr(params, *(outParams->count)), outParams->logContent);
119 }
120 (*(outParams->count))++;
121 ++(*(outParams->pos));
122 break;
123 case 'O':
124 case 'o':
125 if (HilogVector::GetType(params, *(outParams->count)) == OBJECT_TYPE) {
126 HilogString::Puts(
127 showPriv ? PRIV_STR : HilogVector::GetStr(params, *(outParams->count)), outParams->logContent);
128 }
129 (*(outParams->count))++;
130 ++(*(outParams->pos));
131 break;
132 case '%':
133 HilogString::Putc(format[*(outParams->pos)], outParams->logContent);
134 ++(*(outParams->pos));
135 break;
136 default:
137 HilogString::Putc(format[*(outParams->pos)], outParams->logContent);
138 break;
139 }
140 }
141
Debug(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)142 JSIValue HilogModule::Debug(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
143 {
144 return HilogModule::HilogImpl(thisVal, args, argsNum, LogLevel::LOG_DEBUG);
145 }
146
Info(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)147 JSIValue HilogModule::Info(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
148 {
149 return HilogModule::HilogImpl(thisVal, args, argsNum, LogLevel::LOG_INFO);
150 }
151
Error(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)152 JSIValue HilogModule::Error(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
153 {
154 return HilogModule::HilogImpl(thisVal, args, argsNum, LogLevel::LOG_ERROR);
155 }
156
Warn(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)157 JSIValue HilogModule::Warn(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
158 {
159 return HilogModule::HilogImpl(thisVal, args, argsNum, LogLevel::LOG_WARN);
160 }
161
Fatal(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)162 JSIValue HilogModule::Fatal(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
163 {
164 return HilogModule::HilogImpl(thisVal, args, argsNum, LogLevel::LOG_FATAL);
165 }
166
HiLogIsLoggable(int32_t domain,const char * tag,LogLevel level)167 bool HiLogIsLoggable(int32_t domain, const char *tag, LogLevel level)
168 {
169 if ((level < LOG_DEBUG) || (level > LOG_FATAL) || tag == nullptr ||
170 domain > MAX_DOMAIN || domain < MIN_DOMAIN) {
171 return false;
172 }
173 return true;
174 }
175
IsLoggable(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)176 JSIValue HilogModule::IsLoggable(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
177 {
178 if ((args == nullptr) || (argsNum < MIN_NUMBER) || JSI::ValueIsUndefined(args[FIRST]) ||
179 JSI::ValueIsUndefined(args[SECOND]) || JSI::ValueIsUndefined(args[THIRD])) {
180 HILOG_HILOGE("IsLoggable: args is invalid.");
181 return JSI::CreateBoolean(false);
182 }
183 if (JSI::ValueIsNull(args[FIRST]) || JSI::ValueIsNull(args[SECOND]) ||
184 JSI::ValueIsNull(args[THIRD])) {
185 HILOG_HILOGE("IsLoggable: args type is null.");
186 return JSI::CreateBoolean(false);
187 }
188 if (!JSI::ValueIsNumber(args[FIRST]) || !JSI::ValueIsString(args[SECOND]) ||
189 !JSI::ValueIsNumber(args[THIRD])) {
190 HILOG_HILOGE("IsLoggable: args type is invalid.");
191 return JSI::CreateBoolean(false);
192 }
193
194 int32_t domain = static_cast<int32_t>(JSI::ValueToNumber(args[FIRST]));
195 if (domain > MAX_DOMAIN || domain < MIN_DOMAIN) {
196 HILOG_HILOGE("IsLoggable: domain is invalid.");
197 return JSI::CreateBoolean(false);
198 }
199 char *tag = JSI::ValueToString(args[SECOND]);
200 if (tag == nullptr || strlen(tag) > MAX_TAG) {
201 HILOG_HILOGE("IsLoggable: tag is null or tag > %{public}d.", MAX_TAG);
202 return JSI::CreateBoolean(false);
203 }
204 int32_t level = static_cast<int32_t>(JSI::ValueToNumber(args[THIRD]));
205 if (level > LOG_FATAL || level < LOG_DEBUG) {
206 HILOG_HILOGE("IsLoggable:level is error.");
207 JSI::ReleaseString(tag);
208 return JSI::CreateBoolean(false);
209 }
210 bool res = HiLogIsLoggable(domain, tag, static_cast<LogLevel>(level));
211 JSI::ReleaseString(tag);
212 return JSI::CreateBoolean(res);
213 }
214
ParseNapiValue(const JSIValue thisVal,const JSIValue * element,HilogVector * params)215 void HilogModule::ParseNapiValue(const JSIValue thisVal, const JSIValue *element, HilogVector *params)
216 {
217 if (element == nullptr || params == nullptr) {
218 HILOG_HILOGE("ParseNapiValue: element or params is nullptr.");
219 return;
220 }
221 if (JSI::ValueIsNumber(element[0])) {
222 char *value = JSI::JSIValueToString(element[0]);
223 HilogVector::Push(params, value, INT_TYPE);
224 JSI::ReleaseString(value);
225 } else if (JSI::ValueIsString(element[0])) {
226 char *value = JSI::ValueToString(element[0]);
227 HilogVector::Push(params, value, STRING_TYPE);
228 JSI::ReleaseString(value);
229 } else if (JSI::ValueIsObject(element[0])) {
230 char *value = JSI::JSIValueToString(element[0]);
231 HilogVector::Push(params, value, OBJECT_TYPE);
232 JSI::ReleaseString(value);
233 } else {
234 HILOG_HILOGE("ParseNapiValue: type mismatch.");
235 }
236 return;
237 }
238
HilogImpl(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum,int level)239 JSIValue HilogModule::HilogImpl(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum, int level)
240 {
241 JSIValue undefValue = JSI::CreateUndefined();
242 if ((args == nullptr) || (argsNum < MIN_NUMBER) || (argsNum > MAX_NUMBER) ||
243 JSI::ValueIsUndefined(args[FIRST]) || JSI::ValueIsUndefined(args[SECOND]) ||
244 JSI::ValueIsUndefined(args[THIRD]) || JSI::ValueIsNull(args[FIRST]) ||
245 JSI::ValueIsNull(args[SECOND]) || JSI::ValueIsNull(args[THIRD])) {
246 HILOG_HILOGE("HilogImpl: args is invalid.");
247 return undefValue;
248 }
249
250 int32_t domain = static_cast<int32_t>(JSI::ValueToNumber(args[FIRST]));
251 if (domain > MAX_DOMAIN || domain < MIN_DOMAIN) {
252 HILOG_HILOGE("HilogImpl: domain is invalid.");
253 return undefValue;
254 }
255 char *tag = JSI::ValueToString(args[SECOND]);
256 if (tag == nullptr || strlen(tag) > MAX_TAG) {
257 HILOG_HILOGE("HilogImpl: tag is null or tag > %{public}d.", MAX_TAG);
258 return undefValue;
259 }
260 char *fmtString = JSI::ValueToString(args[THIRD]);
261 if (fmtString == nullptr || strlen(fmtString) > MAX_FORMAT) {
262 HILOG_HILOGE("HilogImpl: fmtString is null or fmtString > %{public}d.", MAX_FORMAT);
263 JSI::ReleaseString(tag);
264 return undefValue;
265 }
266
267 HilogVector params;
268 bool result = HilogImplParseValue(thisVal, args, argsNum, ¶ms);
269 if (!result) {
270 JSI::ReleaseString(fmtString);
271 JSI::ReleaseString(tag);
272 return undefValue;
273 }
274 HilogString fmtStringBuffer;
275 HilogString logContent;
276 HilogString::Puts(fmtString, &fmtStringBuffer);
277 ParseLogContent(&fmtStringBuffer, ¶ms, &logContent);
278 if ((HilogString::Length(&logContent) + DOMAIN_LEN + FIX_LEN) + strlen(tag) > (MAX_FORMAT - 1)) {
279 HILOG_HILOGE("HilogImpl: log length > %{public}d.", MAX_FORMAT - DOMAIN_LEN - FIX_LEN - strlen(tag) - 1);
280 JSI::ReleaseString(fmtString);
281 JSI::ReleaseString(tag);
282 return undefValue;
283 }
284 HiLogPrint(DEFAULT_LOG_TYPE, static_cast<LogLevel>(level), domain, tag, HilogString::Get(&logContent), "");
285 JSI::ReleaseString(fmtString);
286 JSI::ReleaseString(tag);
287 return undefValue;
288 }
289
HilogImplParseValue(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum,HilogVector * params)290 bool HilogModule::HilogImplParseValue(
291 const JSIValue thisVal, const JSIValue *args, uint8_t argsNum, HilogVector *params)
292 {
293 if (params == nullptr || args == nullptr) {
294 return false;
295 }
296 if (argsNum > MIN_NUMBER && !JSI::ValueIsUndefined(args[FOURTH]) && !JSI::ValueIsNull(args[FOURTH])) {
297 if (!JSI::ValueIsArray(args[FOURTH])) {
298 for (size_t i = MIN_NUMBER; i < argsNum; i++) {
299 ParseNapiValue(thisVal, &args[i], params);
300 }
301 } else {
302 if (argsNum != MIN_NUMBER + 1) {
303 HILOG_HILOGE("HilogImplParseValue: args mismatch.");
304 return false;
305 }
306 for (uint32_t i = 0; i < JSI::GetArrayLength(args[FOURTH]); i++) {
307 JSIValue element = JSI::GetPropertyByIndex(args[FOURTH], i);
308 ParseNapiValue(thisVal, &element, params);
309 }
310 }
311 }
312 return true;
313 }
314
InitLogLevelType(JSIValue target)315 void InitLogLevelType(JSIValue target)
316 {
317 JSIValue logLevel = JSI::CreateObject();
318 JSI::SetNumberProperty(logLevel, "DEBUG", LogLevel::LOG_DEBUG);
319 JSI::SetNumberProperty(logLevel, "INFO", LogLevel::LOG_INFO);
320 JSI::SetNumberProperty(logLevel, "WARN", LogLevel::LOG_WARN);
321 JSI::SetNumberProperty(logLevel, "ERROR", LogLevel::LOG_ERROR);
322 JSI::SetNumberProperty(logLevel, "FATAL", LogLevel::LOG_FATAL);
323 JSI::SetNamedProperty(target, "LogLevel", logLevel);
324 }
325
InitHilogModule(JSIValue exports)326 void InitHilogModule(JSIValue exports)
327 {
328 HILOG_HILOGI("InitHilogModule start");
329
330 InitLogLevelType(exports);
331 JSI::SetModuleAPI(exports, "debug", HilogModule::Debug);
332 JSI::SetModuleAPI(exports, "info", HilogModule::Info);
333 JSI::SetModuleAPI(exports, "error", HilogModule::Error);
334 JSI::SetModuleAPI(exports, "warn", HilogModule::Warn);
335 JSI::SetModuleAPI(exports, "fatal", HilogModule::Fatal);
336 JSI::SetModuleAPI(exports, "isLoggable", HilogModule::IsLoggable);
337
338 HILOG_HILOGI("InitHilogModule end");
339 }
340 } // ACELite
341 } // OHOS