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 BASE_EVENT_RAW_DECODE_INCLUDE_DECODED_EVENT_H
17 #define BASE_EVENT_RAW_DECODE_INCLUDE_DECODED_EVENT_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <sstream>
22 #include <string>
23 #include <vector>
24 
25 #include "base/raw_data_base_def.h"
26 #include "base/raw_data.h"
27 #include "decoded_param.h"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace EventRaw {
32 class DecodedEvent {
33 public:
34     DecodedEvent(uint8_t* rawData);
35     ~DecodedEvent();
36 
37 public:
38     std::string AsJsonStr();
39     std::shared_ptr<RawData> GetRawData();
40     bool IsValid();
41     const struct HiSysEventHeader& GetHeader();
42     const struct TraceInfo& GetTraceInfo();
43     const std::vector<std::shared_ptr<DecodedParam>>& GetAllCustomizedValues();
44 
45 private:
46     void Parse();
47     void ParseHeader(const size_t maxLen);
48     void ParseCustomizedParams(const size_t maxLen);
49     std::shared_ptr<DecodedParam> ParseCustomizedParam(const size_t maxLen);
50 
51 private:
52     template<typename T>
AppendValue(std::stringstream & ss,const std::string & key,T val)53     void AppendValue(std::stringstream& ss, const std::string& key, T val)
54     {
55         if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
56             ss << "\"" << key << "\":\"" << val << "\",";
57             return;
58         }
59         if constexpr (std::is_same_v<std::decay_t<T>, bool> ||
60             std::is_same_v<std::decay_t<T>, int8_t> ||
61             std::is_same_v<std::decay_t<T>, uint8_t> ||
62             std::is_same_v<std::decay_t<T>, int16_t> ||
63             std::is_same_v<std::decay_t<T>, uint16_t> ||
64             std::is_same_v<std::decay_t<T>, int32_t> ||
65             std::is_same_v<std::decay_t<T>, uint32_t> ||
66             std::is_same_v<std::decay_t<T>, int64_t> ||
67             std::is_same_v<std::decay_t<T>, uint64_t> ||
68             std::is_same_v<std::decay_t<T>, float> ||
69             std::is_same_v<std::decay_t<T>, double>) {
70             ss << "\"" << key << "\":" << val << ",";
71             return;
72         }
73         AppendArrayValue(ss, key, val);
74     }
75 
76     template<typename T>
AppendArrayValue(std::stringstream & ss,const std::string & key,T vals)77     void AppendArrayValue(std::stringstream& ss, const std::string& key, T vals)
78     {
79         ss << "\"" << key << "\":";
80         ss << "[";
81         bool arrayIsNotEmpty = false;
82         if constexpr (std::is_same_v<std::decay_t<T>, std::vector<std::string>>) {
83             arrayIsNotEmpty = (vals.size() > 0);
84             for (auto item : vals) {
85                 ss << "\"" << item << "\",";
86             }
87         }
88         if constexpr (std::is_same_v<std::decay_t<T>, std::vector<bool>> ||
89             std::is_same_v<std::decay_t<T>, std::vector<int8_t>> ||
90             std::is_same_v<std::decay_t<T>, std::vector<uint8_t>> ||
91             std::is_same_v<std::decay_t<T>, std::vector<int16_t>> ||
92             std::is_same_v<std::decay_t<T>, std::vector<uint16_t>> ||
93             std::is_same_v<std::decay_t<T>, std::vector<int32_t>> ||
94             std::is_same_v<std::decay_t<T>, std::vector<uint32_t>> ||
95             std::is_same_v<std::decay_t<T>, std::vector<int64_t>> ||
96             std::is_same_v<std::decay_t<T>, std::vector<uint64_t>> ||
97             std::is_same_v<std::decay_t<T>, std::vector<float>> ||
98             std::is_same_v<std::decay_t<T>, std::vector<double>>) {
99             arrayIsNotEmpty = (vals.size() > 0);
100             for (auto item : vals) {
101                 ss << "" << item << ",";
102             }
103         }
104         if (ss.tellp() != 0 && arrayIsNotEmpty) {
105             ss.seekp(-1, std::ios_base::end);
106         }
107         ss << "],";
108     }
109 
110     void AppendBaseInfo(std::stringstream& ss);
111     void AppendCustomizedArrayParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param);
112     void AppendCustomizedParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param);
113     void AppendCustomizedParams(std::stringstream& ss);
114 
115 private:
116     std::shared_ptr<DecodedParam> CreateFloatingNumTypeDecodedParam(const size_t maxLen, const std::string& key,
117         bool isArray);
118     std::shared_ptr<DecodedParam> CreateSignedVarintTypeDecodedParam(const size_t maxLen, const std::string& key,
119         bool isArray);
120     std::shared_ptr<DecodedParam> CreateStringTypeDecodedParam(const size_t maxLen, const std::string& key,
121         bool isArray);
122     std::shared_ptr<DecodedParam> CreateUnsignedVarintTypeDecodedParam(const size_t maxLen, const std::string& key,
123         bool isArray);
124 
125 private:
126     uint8_t* rawData_ = nullptr;
127     size_t pos_ = 0;
128     struct HiSysEventHeader header_ = {
129         .domain = {0},
130         .name = {0},
131         .timestamp = 0,
132         .timeZone = 0,
133         .uid = 0,
134         .pid = 0,
135         .tid = 0,
136         .id = 0,
137         .type = 0,
138         .isTraceOpened = 0,
139         .log = 0,
140     };
141     struct TraceInfo traceInfo_ {
142         .traceFlag = 0,
143         .traceId = 0,
144         .spanId = 0,
145         .pSpanId = 0,
146     };
147     bool isValid_ = false;
148     std::vector<std::shared_ptr<DecodedParam>> allParams_;
149 };
150 } // namespace EventRaw
151 } // namespace HiviewDFX
152 } // namespace OHOS
153 
154 #endif // BASE_EVENT_RAW_DECODE_INCLUDE_DECODED_EVENT_H
155