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