1 /* 2 * Copyright (c) 2021-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 #ifndef UTIL_EX_H 16 #define UTIL_EX_H 17 18 #include <map> 19 #include <vector> 20 #include <string> 21 #include <ctime> 22 #include <type_traits> 23 #include "define_multimodal.h" 24 #include "mmi_log.h" 25 #include "securec.h" 26 #include "struct_multimodal.h" 27 #include "util.h" 28 29 namespace OHOS { 30 namespace MMI { 31 template<class ...Ts> mprintf(int32_t fd,const char * fmt,Ts...args)32 int32_t mprintf(int32_t fd, const char* fmt, Ts... args) 33 { 34 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "UtilEx" }; 35 if (fmt == nullptr) { 36 return RET_ERR; 37 } 38 39 constexpr size_t bufSize = 1024 * 10; 40 char buf[bufSize] = {}; 41 int32_t ret = snprintf_s(buf, bufSize, bufSize - 1, fmt, args...); 42 if (ret < 0) { 43 return ret; 44 } 45 46 if (fd < 0) { 47 ret = printf("%s\n", buf); 48 } else if (fd == 0) { 49 MMI_LOGF("%{public}s", buf); 50 } else { 51 ret = dprintf(fd, "%s\n", buf); 52 } 53 return ret; 54 } 55 56 template<class ...Ts> DumpData(const char * dataPtr,const size_t dataSize,const char * fileName,const int32_t lineNo,const char * titleFormat,Ts...args)57 void DumpData(const char* dataPtr, const size_t dataSize, const char* fileName, const int32_t lineNo, 58 const char* titleFormat, Ts... args) 59 { 60 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "UtilEx" }; 61 62 constexpr size_t outBufSize = 1024; 63 char outBuf[outBufSize] = {}; 64 int32_t writeLen = 0; 65 int32_t ret; 66 auto funcAdvanceWriteLen = [&writeLen, ret]() { 67 if (ret > 0) { 68 writeLen += ret; 69 } 70 }; 71 72 auto funcOutput = [&writeLen, &ret, &outBuf, outBufSize]() { 73 (void)memset_s(&outBuf[0], sizeof(outBuf), 0, sizeof(outBuf)); 74 writeLen = 0; 75 ret = 0; 76 }; 77 78 ret = sprintf_s(outBuf, outBufSize - writeLen, "[%s]", OHOS::MMI::GetProgramName()); 79 funcAdvanceWriteLen(ret); 80 ret = sprintf_s(outBuf, outBufSize - writeLen, titleFormat, args...); 81 funcAdvanceWriteLen(ret); 82 ret = sprintf_s(outBuf, outBufSize - writeLen, " data size = %zu. %s:%d\n", dataSize, fileName, lineNo); 83 funcAdvanceWriteLen(ret); 84 85 funcOutput(); 86 87 constexpr size_t bufSize = 81; 88 constexpr size_t oneLineCharCount = 16; 89 constexpr size_t countStep = 2; 90 constexpr size_t byteSize = 8; 91 constexpr size_t wordSize = 16; 92 char bufLeft[bufSize] = {}; 93 char bufRight[bufSize] = {}; 94 size_t writePosHex = 0; 95 size_t writePosChar = 0; 96 constexpr size_t writePosHexStep1 = 2; 97 constexpr size_t writePosHexStep2 = 3; 98 size_t i = 0; 99 auto funCheckRetAndLog = [ret](const char* fileName, const int32_t lineNo) -> void { 100 if (ret == -1) { 101 MMI_LOGE("SEC_RET_EQ: ret:%{public}d, %s:%d", ret, fileName, lineNo); 102 } 103 }; 104 105 for (i = 0; i < dataSize; i++) { 106 const unsigned char c = static_cast<unsigned char>(dataPtr[i]); 107 ret = sprintf_s(bufLeft + writePosHex, bufSize - writePosHex, "%02x ", c); 108 funCheckRetAndLog(MMI_LINE_INFO); 109 if (i != 0 && (i + 1) % byteSize == 0 && (i + 1) % wordSize != 0) { 110 ret = sprintf_s(bufLeft + writePosHex, bufSize - writePosHex, "- "); 111 funCheckRetAndLog(MMI_LINE_INFO); 112 writePosHex += writePosHexStep1; 113 } else { 114 writePosHex += writePosHexStep2; 115 } 116 if (isprint(c)) { 117 ret = sprintf_s(bufRight + writePosChar, bufSize - writePosChar, "%c", c); 118 funCheckRetAndLog(MMI_LINE_INFO); 119 writePosChar += 1; 120 } else { 121 ret = sprintf_s(bufRight + writePosChar, bufSize - writePosChar, "%c", ' '); 122 funCheckRetAndLog(MMI_LINE_INFO); 123 writePosChar += 1; 124 } 125 if ((i != 0) && ((i + 1) % oneLineCharCount == 0)) { 126 ret = sprintf_s(outBuf, outBufSize - writeLen, "%04zu-%04zu %s %s\n", 127 i - (oneLineCharCount - 1), i, bufLeft, bufRight); 128 funcAdvanceWriteLen(ret); 129 funcOutput(); 130 (void)memset_s(bufLeft, sizeof(bufLeft), 0, sizeof(bufLeft)); 131 (void)memset_s(bufRight, sizeof(bufRight), 0, sizeof(bufRight)); 132 writePosHex = 0; 133 writePosChar = 0; 134 } 135 } 136 137 if (writePosHex != 0) { 138 size_t ibefore = 0; 139 if (i > (oneLineCharCount - 1)) { 140 i = ((i + (oneLineCharCount - countStep)) % (oneLineCharCount - 1)) - (oneLineCharCount - 1); 141 } 142 size_t iafter = ((i + (oneLineCharCount - 2)) % (oneLineCharCount - 1)); 143 ret = sprintf_s(outBuf, outBufSize - writeLen, "%04zu-%04zu %s %s\n", ibefore, iafter, bufLeft, bufRight); 144 funcAdvanceWriteLen(ret); 145 funcOutput(); 146 } 147 } 148 149 template <class Enum> 150 constexpr auto EnumUnderlyingValue(Enum const e) -> typename std::underlying_type<Enum>::type 151 { 152 static_assert(std::is_enum<Enum>::value, "input value is not of enum class nor enum"); 153 return static_cast<typename std::underlying_type<Enum>::type>(e); 154 } 155 156 template <class Enum, class T> EnumAdd(Enum const e,T val)157 Enum EnumAdd(Enum const e, T val) 158 { 159 static_assert(std::is_enum<Enum>::value, "input value is not of enum class nor enum"); 160 auto a = EnumUnderlyingValue(e); 161 return static_cast<Enum>(a + val); 162 } 163 } // namespace MMI 164 } // namespace OHOS 165 166 #endif // UTIL_EX_H