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 #ifndef RS_PROFILER_MESSAGE_HELPER_H
17 #define RS_PROFILER_MESSAGE_HELPER_H
18 
19 #include "rs_profiler_utils.h"
20 
21 #include <bitset>
22 #include <iterator>
23 #include <type_traits>
24 #include <vector>
25 
26 #ifndef REPLAY_TOOL_CLIENT
27 #include <securec.h>
28 #endif
29 
30 namespace OHOS::Rosen {
31 
32 enum class PackageID {
33     RS_PROFILER_HEADER,
34     RS_PROFILER_BINARY,
35     RS_PROFILER_RS_METRICS,
36     RS_PROFILER_GFX_METRICS,
37     RS_PROFILER_PREPARE,
38     RS_PROFILER_PREPARE_DONE,
39     RS_PROFILER_SKP_BINARY,
40     RS_PROFILER_RDC_BINARY,
41     RS_PROFILER_DCL_BINARY,
42     RS_PROFILER_RSTREE_DUMP_JSON,
43     RS_PROFILER_RSTREE_PERF_NODE_LIST,
44     RS_PROFILER_RSTREE_SINGLE_NODE_PERF,
45     RS_PROFILER_MSKP_FILEPATH,
46     RS_PROFILER_BETAREC_FILEPATH,
47     RS_PROFILER_RENDER_METRICS,
48 };
49 class BinaryHelper {
50 public:
51     BinaryHelper() = delete;
52     BinaryHelper(const BinaryHelper&) = delete;
53     BinaryHelper(BinaryHelper&&) = delete;
54     BinaryHelper& operator=(const BinaryHelper&) = delete;
55     BinaryHelper& operator=(BinaryHelper&&) = delete;
56 
Type(const char * data)57     static PackageID Type(const char* data)
58     {
59         return static_cast<PackageID>(data[0]);
60     }
Data(const char * data,int len)61     static std::vector<char> Data(const char* data, int len)
62     {
63         return std::vector<char>(data + 1, data + len);
64     }
BinaryCount(const char * data)65     static uint32_t BinaryCount(const char* data)
66     {
67         return *reinterpret_cast<const uint32_t*>(data + 1);
68     }
Pid(const char * data)69     static uint16_t Pid(const char* data)
70     {
71         return *reinterpret_cast<const uint16_t*>(data + 1 + sizeof(uint32_t));
72     }
73 };
74 
75 template<typename T, typename = void>
76 struct HasContiguousLayout : std::false_type {};
77 
78 template<typename T>
79 struct HasContiguousLayout<T, std::void_t<decltype(std::declval<T>().data())>> : std::true_type {};
80 
81 class Packet {
82 public:
83     enum PacketType : uint8_t {
84         BINARY,
85         COMMAND,
86         LOG,
87         UNKNOWN,
88     };
89 
90     enum class Severity {
91         LOG_CRITICAL,
92         LOG_ERROR,
93         LOG_INFO,
94         LOG_DEBUG,
95         LOG_TRACE,
96     };
97 
98     static constexpr size_t HEADER_SIZE = sizeof(uint32_t) + sizeof(uint8_t);
99 
100     explicit Packet(PacketType type, uint32_t reserve = DEFAULT_RESERVED_SIZE);
101     Packet(const Packet&) = default;
102     Packet& operator=(const Packet&) = default;
103     Packet(Packet&&) = default;
104     Packet& operator=(Packet&&) = default;
105 
106     bool IsBinary() const;
107 
108     bool IsCommand() const;
109 
110     char* Begin();
111 
112     char* End();
113 
114     PacketType GetType() const;
115     void SetType(PacketType type);
116     uint32_t GetLength() const;
117     uint32_t GetPayloadLength() const;
118 
119     std::vector<char> Release();
120 
121     template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
122     [[maybe_unused]] bool Read(T& value);
123 
124     template<typename T>
125     [[maybe_unused]] bool Read(T& value, size_t size);
126 
127     [[maybe_unused]] bool Read(void* value, size_t size);
128 
129     template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
130     T Read();
131 
132     template<typename T>
133     T Read(size_t size);
134 
135     template<typename T>
136     [[maybe_unused]] bool Write(const T& value);
137 
138     [[maybe_unused]] bool Write(const void* value, size_t size);
139 
140 private:
141     void SetLength(uint32_t length);
142 
143     void InitData(PacketType type);
144 
145 private:
146     static constexpr size_t HEADER_TYPE_OFFSET = 0;
147     static constexpr size_t HEADER_LENGTH_OFFSET = sizeof(uint8_t);
148     static constexpr size_t DEFAULT_RESERVED_SIZE = 64;
149     size_t readPointer_ = HEADER_SIZE;
150     size_t writePointer_ = HEADER_SIZE;
151     std::vector<char> data_ = { 0, 0, 0, 0, 0 };
152 };
153 
154 template<typename T, typename>
155 [[maybe_unused]] inline bool Packet::Read(T& value)
156 {
157     return Read(&value, sizeof(value));
158 }
159 
160 template<typename T>
161 [[maybe_unused]] bool Packet::Read(T& value, size_t size)
162 {
163     if constexpr (HasContiguousLayout<T>::value) {
164         value.resize(size);
165         return Read(value.data(), size * sizeof(typename T::value_type));
166     } else {
167         bool res = true;
168         for (size_t i = 0; i < size; ++i) {
169             typename T::value_type v {};
170             res = res && Read(v);
171             value.emplace(std::move(v));
172         }
173         return res;
174     }
175     return false;
176 }
177 
178 template<typename T, typename>
179 inline T Packet::Read()
180 {
181     T v {};
182     Read(v);
183     return v;
184 }
185 
186 template<typename T>
187 inline T Packet::Read(size_t size)
188 {
189     T v {};
190     Read(v, size);
191     return v;
192 }
193 
194 template<typename T>
195 [[maybe_unused]] bool Packet::Write(const T& value)
196 {
197     if constexpr (std::is_trivially_copyable_v<T>) {
198         return Write(&value, sizeof(value));
199     } else if constexpr (HasContiguousLayout<T>::value) {
200         return Write(value.data(), value.size() * sizeof(typename T::value_type));
201     } else {
202         bool res = true;
203         for (auto it = value.cbegin(); it != value.cend(); ++it) {
204             res = res && Write(*it);
205         }
206         return res;
207     }
208     return false;
209 }
210 
211 } // namespace OHOS::Rosen
212 
213 #endif // RS_PROFILER_MESSAGE_HELPER_H
214