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