1 /*
2 * Copyright (c) 2024 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 "content_reader.h"
17
18 #include "base/raw_data_base_def.h"
19 #include "base/raw_data.h"
20 #include "encoded/encoded_param.h"
21 #include "hiview_logger.h"
22 #include "securec.h"
23 #include "sys_event.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("HiView-ContentReader");
28 using namespace EventStore;
29 namespace {
30 constexpr uint32_t DATA_FORMAT_VERSION_OFFSET =
31 sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint8_t); // magicNumber + blockSize + pageSize
32
UpdateParamCnt(std::shared_ptr<RawData> rawData,int32_t addParamCnt)33 bool UpdateParamCnt(std::shared_ptr<RawData> rawData, int32_t addParamCnt)
34 {
35 uint32_t pos = BLOCK_SIZE + sizeof(struct EventRaw::HiSysEventHeader);
36 auto header = *(reinterpret_cast<struct EventRaw::HiSysEventHeader*>(rawData->GetData() + BLOCK_SIZE));
37 if (header.isTraceOpened == 1) { // 1: include trace info, 0: exclude trace info
38 pos += sizeof(struct EventRaw::TraceInfo);
39 }
40 int32_t paramCnt = *(reinterpret_cast<int32_t*>(rawData->GetData() + pos)) + addParamCnt;
41 return rawData->Update(reinterpret_cast<uint8_t*>(¶mCnt), sizeof(int32_t), pos);
42 }
43
UpdateRealSize(std::shared_ptr<RawData> rawData)44 bool UpdateRealSize(std::shared_ptr<RawData> rawData)
45 {
46 uint32_t realSize = rawData->GetDataLength();
47 return rawData->Update(reinterpret_cast<uint8_t*>(&realSize), BLOCK_SIZE, 0);
48 }
49 }
50
ReadFmtVersion(std::ifstream & docStream)51 uint8_t ContentReader::ReadFmtVersion(std::ifstream& docStream)
52 {
53 if (!docStream.is_open()) {
54 return EventStore::EVENT_DATA_FORMATE_VERSION::INVALID;
55 }
56 auto curPos = docStream.tellg();
57 docStream.seekg(DATA_FORMAT_VERSION_OFFSET, std::ios::beg);
58 uint8_t dataFmtVersion = EventStore::EVENT_DATA_FORMATE_VERSION::INVALID;
59 docStream.read(reinterpret_cast<char*>(&dataFmtVersion), sizeof(uint8_t));
60 docStream.seekg(curPos, std::ios::beg);
61 return dataFmtVersion;
62 }
63
ReadRawData(const EventInfo & eventInfo,uint8_t * content,uint32_t contentSize)64 std::shared_ptr<RawData> ContentReader::ReadRawData(const EventInfo& eventInfo, uint8_t* content, uint32_t contentSize)
65 {
66 constexpr uint32_t expandSize = 128; // for seq, tag, level
67 // the different size of event header between old and newer version.
68 uint32_t eventSize = contentSize - GetContentHeaderSize() + sizeof(EventStore::ContentHeader) -
69 SEQ_SIZE + MAX_DOMAIN_LEN + MAX_EVENT_NAME_LEN + expandSize;
70 if (eventSize > MAX_NEW_SIZE) {
71 HIVIEW_LOGE("invalid new event size=%{public}u", eventSize);
72 return nullptr;
73 }
74 auto rawData = std::make_shared<RawData>(eventSize);
75 if (!rawData->Append(reinterpret_cast<uint8_t*>(&eventSize), BLOCK_SIZE)) {
76 HIVIEW_LOGE("failed to copy event size to raw event");
77 return nullptr;
78 }
79 if (AppendDomainAndName(rawData, eventInfo) != DOC_STORE_SUCCESS) {
80 return nullptr;
81 }
82 if (AppendContentData(rawData, content, contentSize) != DOC_STORE_SUCCESS) {
83 return nullptr;
84 }
85 if (AppendExtraInfo(rawData, eventInfo)) {
86 return nullptr;
87 }
88 return rawData;
89 }
90
AppendDomainAndName(std::shared_ptr<RawData> rawData,const EventInfo & eventInfo)91 int ContentReader::AppendDomainAndName(std::shared_ptr<RawData> rawData, const EventInfo& eventInfo)
92 {
93 if (!rawData->Append(reinterpret_cast<uint8_t*>(const_cast<char*>(eventInfo.domain)), MAX_DOMAIN_LEN)) {
94 HIVIEW_LOGE("failed to copy domain to raw event");
95 return DOC_STORE_ERROR_MEMORY;
96 }
97 if (!rawData->Append(reinterpret_cast<uint8_t*>(const_cast<char*>(eventInfo.name)), MAX_EVENT_NAME_LEN)) {
98 HIVIEW_LOGE("failed to copy name to raw event");
99 return DOC_STORE_ERROR_MEMORY;
100 }
101 return DOC_STORE_SUCCESS;
102 }
103
AppendContentData(std::shared_ptr<RawData> rawData,uint8_t * content,uint32_t contentSize)104 int ContentReader::AppendContentData(std::shared_ptr<RawData> rawData, uint8_t* content, uint32_t contentSize)
105 {
106 EventStore::ContentHeader contentHeader;
107 if (GetContentHeader(content, contentHeader) != DOC_STORE_SUCCESS) {
108 HIVIEW_LOGE("failed to get header of content");
109 return DOC_STORE_ERROR_MEMORY;
110 }
111 if (!rawData->Append(reinterpret_cast<uint8_t*>(&contentHeader) + SEQ_SIZE,
112 sizeof(EventStore::ContentHeader) - SEQ_SIZE)) {
113 HIVIEW_LOGE("failed to copy content header to raw event");
114 return DOC_STORE_ERROR_MEMORY;
115 }
116 size_t contentPos = BLOCK_SIZE + GetContentHeaderSize();
117 if (!rawData->Append(content + contentPos, contentSize - contentPos - CRC_SIZE)) {
118 HIVIEW_LOGE("failed to copy content data to raw event");
119 return DOC_STORE_ERROR_MEMORY;
120 }
121 return DOC_STORE_SUCCESS;
122 }
123
AppendExtraInfo(std::shared_ptr<RawData> rawData,const EventInfo & eventInfo)124 int ContentReader::AppendExtraInfo(std::shared_ptr<RawData> rawData, const EventInfo& eventInfo)
125 {
126 uint32_t addParamCnt = 2; // for seq, level
127 if (AppendTag(rawData, eventInfo.tag) == DOC_STORE_SUCCESS) {
128 addParamCnt++;
129 }
130 if (auto ret = AppendLevel(rawData, eventInfo.level); ret != DOC_STORE_SUCCESS) {
131 return ret;
132 }
133 if (auto ret = AppendSeq(rawData, eventInfo.seq); ret != DOC_STORE_SUCCESS) {
134 return ret;
135 }
136 if (!UpdateParamCnt(rawData, addParamCnt)) {
137 HIVIEW_LOGE("failed to update paramCnt to raw event");
138 return DOC_STORE_ERROR_MEMORY;
139 }
140 if (!UpdateRealSize(rawData)) {
141 HIVIEW_LOGE("failed to update realSize of raw event");
142 return DOC_STORE_ERROR_MEMORY;
143 }
144 return DOC_STORE_SUCCESS;
145 }
146
AppendTag(std::shared_ptr<RawData> rawData,const std::string & tag)147 int ContentReader::AppendTag(std::shared_ptr<RawData> rawData, const std::string& tag)
148 {
149 if (tag.empty()) {
150 return DOC_STORE_ERROR_INVALID;
151 }
152 auto tagParam = std::make_shared<EventRaw::StringEncodedParam>(EventCol::TAG, tag);
153 auto& tagRawData = tagParam->GetRawData();
154 if (!rawData->Append(tagRawData.GetData(), tagRawData.GetDataLength())) {
155 HIVIEW_LOGE("failed to copy tag to raw event");
156 return DOC_STORE_ERROR_MEMORY;
157 }
158 return DOC_STORE_SUCCESS;
159 }
160
AppendLevel(std::shared_ptr<RawData> rawData,const std::string & level)161 int ContentReader::AppendLevel(std::shared_ptr<RawData> rawData, const std::string& level)
162 {
163 auto levelParam = std::make_shared<EventRaw::StringEncodedParam>(EventCol::LEVEL, level);
164 auto& levelRawData = levelParam->GetRawData();
165 if (!rawData->Append(levelRawData.GetData(), levelRawData.GetDataLength())) {
166 HIVIEW_LOGE("failed to copy level to raw event");
167 return DOC_STORE_ERROR_MEMORY;
168 }
169 return DOC_STORE_SUCCESS;
170 }
171
AppendSeq(std::shared_ptr<RawData> rawData,int64_t seq)172 int ContentReader::AppendSeq(std::shared_ptr<RawData> rawData, int64_t seq)
173 {
174 auto seqParam = std::make_shared<EventRaw::SignedVarintEncodedParam<int64_t>>(EventCol::SEQ, seq);
175 auto& seqRawData = seqParam->GetRawData();
176 if (!rawData->Append(seqRawData.GetData(), seqRawData.GetDataLength())) {
177 HIVIEW_LOGE("failed to copy seq to raw event");
178 return DOC_STORE_ERROR_MEMORY;
179 }
180 return DOC_STORE_SUCCESS;
181 }
182
GetDataString(std::ifstream & docStream,std::string & value)183 bool ContentReader::GetDataString(std::ifstream& docStream, std::string& value)
184 {
185 uint32_t valueSize = 0;
186 docStream.read(reinterpret_cast<char*>(&valueSize), sizeof(uint32_t));
187 if (valueSize > (MAX_VERSION_LENG + 1) || valueSize == 0) { // end with '\0'
188 HIVIEW_LOGE("version size is invalid, size=%{public}" PRIu32 "", valueSize);
189 return false;
190 }
191
192 char valueStr[valueSize];
193 docStream.read(valueStr, valueSize);
194 value = std::string(valueStr);
195 return true;
196 }
197 } // HiviewDFX
198 } // OHOS